LCOV - code coverage report
Current view: directory - port - cplstring.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 119 107 89.9 %
Date: 2012-04-28 Functions: 11 10 90.9 %

       1                 : /******************************************************************************
       2                 :  * $Id: cplstring.cpp 23406 2011-11-21 19:29:41Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL 
       5                 :  * Purpose:  CPLString implementation.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "cpl_string.h"
      31                 : #include <string>
      32                 : 
      33                 : CPL_CVSID("$Id: cplstring.cpp 23406 2011-11-21 19:29:41Z rouault $");
      34                 : 
      35                 : /*
      36                 :  * The CPLString class is derived from std::string, so the vast majority 
      37                 :  * of the implementation comes from that.  This module is just the extensions
      38                 :  * we add. 
      39                 :  */
      40                 : 
      41                 : /************************************************************************/
      42                 : /*                               Printf()                               */
      43                 : /************************************************************************/
      44                 : 
      45          266899 : CPLString &CPLString::Printf( const char *pszFormat, ... )
      46                 : 
      47                 : {
      48                 :     va_list args;
      49                 : 
      50          266899 :     va_start( args, pszFormat );
      51          266899 :     vPrintf( pszFormat, args );
      52          266899 :     va_end( args );
      53                 : 
      54          266899 :     return *this;
      55                 : }
      56                 : 
      57                 : /************************************************************************/
      58                 : /*                              vPrintf()                               */
      59                 : /************************************************************************/
      60                 : 
      61          312725 : CPLString &CPLString::vPrintf( const char *pszFormat, va_list args )
      62                 : 
      63                 : {
      64                 : /* -------------------------------------------------------------------- */
      65                 : /*      This implementation for platforms without vsnprintf() will      */
      66                 : /*      just plain fail if the formatted contents are too large.        */
      67                 : /* -------------------------------------------------------------------- */
      68                 : 
      69                 : #if !defined(HAVE_VSNPRINTF)
      70                 :     char *pszBuffer = (char *) CPLMalloc(30000);
      71                 :     if( vsprintf( pszBuffer, pszFormat, args) > 29998 )
      72                 :     {
      73                 :         CPLError( CE_Fatal, CPLE_AppDefined, 
      74                 :                   "CPLString::vPrintf() ... buffer overrun." );
      75                 :     }
      76                 :     *this = pszBuffer;
      77                 :     CPLFree( pszBuffer );
      78                 : 
      79                 : /* -------------------------------------------------------------------- */
      80                 : /*      This should grow a big enough buffer to hold any formatted      */
      81                 : /*      result.                                                         */
      82                 : /* -------------------------------------------------------------------- */
      83                 : #else
      84                 :     char szModestBuffer[500];
      85                 :     int nPR;
      86                 :     va_list wrk_args;
      87                 : 
      88                 : #ifdef va_copy
      89          312725 :     va_copy( wrk_args, args );
      90                 : #else
      91                 :     wrk_args = args;
      92                 : #endif
      93                 :     
      94                 :     nPR = vsnprintf( szModestBuffer, sizeof(szModestBuffer), pszFormat, 
      95          312725 :                      wrk_args );
      96          314832 :     if( nPR == -1 || nPR >= (int) sizeof(szModestBuffer)-1 )
      97                 :     {
      98            2107 :         int nWorkBufferSize = 2000;
      99            2107 :         char *pszWorkBuffer = (char *) CPLMalloc(nWorkBufferSize);
     100                 : 
     101                 : #ifdef va_copy
     102            2107 :         va_end( wrk_args );
     103            2107 :         va_copy( wrk_args, args );
     104                 : #else
     105                 :         wrk_args = args;
     106                 : #endif
     107            4312 :         while( (nPR=vsnprintf( pszWorkBuffer, nWorkBufferSize, pszFormat,wrk_args))
     108                 :                >= nWorkBufferSize-1 
     109                 :                || nPR == -1 )
     110                 :         {
     111              98 :             nWorkBufferSize *= 4;
     112                 :             pszWorkBuffer = (char *) CPLRealloc(pszWorkBuffer, 
     113              98 :                                                 nWorkBufferSize );
     114                 : #ifdef va_copy
     115              98 :             va_end( wrk_args );
     116              98 :             va_copy( wrk_args, args );
     117                 : #else
     118                 :             wrk_args = args;
     119                 : #endif
     120                 :         }
     121            2107 :         *this = pszWorkBuffer;
     122            2107 :         CPLFree( pszWorkBuffer );
     123                 :     }
     124                 :     else
     125                 :     {
     126          310618 :         *this = szModestBuffer;
     127                 :     }
     128          312725 :     va_end( wrk_args );
     129                 : #endif
     130                 : 
     131          312725 :     return *this;
     132                 : }
     133                 : 
     134                 : /************************************************************************/
     135                 : /*                              FormatC()                               */
     136                 : /************************************************************************/
     137                 : 
     138                 : /**
     139                 :  * Format double in C locale.
     140                 :  * 
     141                 :  * The passed value is formatted using the C locale (period as decimal 
     142                 :  * seperator) and appended to the target CPLString. 
     143                 :  *
     144                 :  * @param dfValue the value to format. 
     145                 :  * @param pszFormat the sprintf() style format to use or omit for default.
     146                 :  * Note that this format string should only include one substitution argument 
     147                 :  * and it must be for a double (%f or %g). 
     148                 :  *
     149                 :  * @return a reference to the CPLString. 
     150                 :  */
     151                 : 
     152             846 : CPLString &CPLString::FormatC( double dfValue, const char *pszFormat )
     153                 : 
     154                 : {
     155             846 :     if( pszFormat == NULL )
     156              12 :         pszFormat = "%g";
     157                 : 
     158                 :     char szWork[512]; // presumably long enough for any number?
     159                 : 
     160             846 :     sprintf( szWork, pszFormat, dfValue );
     161             846 :     CPLAssert( strlen(szWork) < sizeof(szWork) );
     162                 :     
     163             846 :     if( strchr( szWork, ',' ) != NULL )
     164                 :     {
     165               0 :         char *pszDelim = strchr( szWork, ',' );
     166               0 :         *pszDelim = '.';
     167                 :     }
     168                 : 
     169             846 :     *this += szWork;
     170                 :     
     171             846 :     return *this;
     172                 : }
     173                 : 
     174                 : /************************************************************************/
     175                 : /*                                Trim()                                */
     176                 : /************************************************************************/
     177                 : 
     178                 : /**
     179                 :  * Trim white space.
     180                 :  *
     181                 :  * Trims white space off the let and right of the string.  White space
     182                 :  * is any of a space, a tab, a newline ('\n') or a carriage control ('\r').
     183                 :  *
     184                 :  * @return a reference to the CPLString. 
     185                 :  */
     186                 : 
     187           44042 : CPLString &CPLString::Trim()
     188                 : 
     189                 : {
     190                 :     size_t iLeft, iRight;
     191                 :     static const char szWhitespace[] = " \t\r\n";
     192                 : 
     193           44042 :     iLeft = find_first_not_of( szWhitespace );
     194           44042 :     iRight = find_last_not_of( szWhitespace );
     195                 : 
     196           44042 :     if( iLeft == std::string::npos )
     197                 :     {
     198           10032 :         erase();
     199           10032 :         return *this;
     200                 :     }
     201                 :     
     202           34010 :     assign( substr( iLeft, iRight - iLeft + 1 ) );
     203                 : 
     204           34010 :     return *this;
     205                 : }
     206                 : 
     207                 : /************************************************************************/
     208                 : /*                               Recode()                               */
     209                 : /************************************************************************/
     210                 : 
     211             604 : CPLString &CPLString::Recode( const char *pszSrcEncoding,
     212                 :                               const char *pszDstEncoding )
     213                 : 
     214                 : {
     215             604 :     if( pszSrcEncoding == NULL )
     216               0 :         pszSrcEncoding = CPL_ENC_UTF8;
     217             604 :     if( pszDstEncoding == NULL )
     218               0 :         pszDstEncoding = CPL_ENC_UTF8;
     219                 : 
     220             604 :     if( strcmp(pszSrcEncoding,pszDstEncoding) == 0 )
     221               0 :         return *this;
     222                 : 
     223                 :     char *pszRecoded = CPLRecode( c_str(), 
     224                 :                                   pszSrcEncoding,
     225             604 :                                   pszDstEncoding );
     226                 : 
     227             604 :     if( pszRecoded == NULL )
     228               0 :         return *this;
     229                 : 
     230             604 :     assign( pszRecoded );
     231             604 :     CPLFree( pszRecoded );
     232                 : 
     233             604 :     return *this;
     234                 : }
     235                 : 
     236                 : /************************************************************************/
     237                 : /*                               ifind()                                */
     238                 : /************************************************************************/
     239                 : 
     240                 : /** 
     241                 :  * Case insensitive find() alternative.
     242                 :  *
     243                 :  * @param str substring to find.
     244                 :  * @param pos offset in the string at which the search starts.
     245                 :  * @return the position of substring in the string or std::string::npos if not found.
     246                 :  * @since GDAL 1.9.0
     247                 :  */
     248                 : 
     249            1300 : size_t CPLString::ifind( const std::string & str, size_t pos ) const
     250                 : 
     251                 : {
     252            1300 :     return ifind( str.c_str(), pos );
     253                 : }
     254                 : 
     255                 : /**
     256                 :  * Case insensitive find() alternative.
     257                 :  *
     258                 :  * @param s substring to find.
     259                 :  * @param nPos offset in the string at which the search starts.
     260                 :  * @return the position of the substring in the string or std::string::npos if not found.
     261                 :  * @since GDAL 1.9.0
     262                 :  */
     263                 : 
     264           27330 : size_t CPLString::ifind( const char *s, size_t nPos ) const
     265                 : 
     266                 : {
     267           27330 :     const char *pszHaystack = c_str();
     268           27330 :     char chFirst = (char) ::tolower( s[0] );
     269           27330 :     int nTargetLen = strlen(s);
     270                 : 
     271           27330 :     if( nPos > size() )
     272               0 :         nPos = size();
     273                 : 
     274           27330 :     pszHaystack += nPos;
     275                 : 
     276          936344 :     while( *pszHaystack != '\0' )
     277                 :     {
     278          883530 :         if( chFirst == ::tolower(*pszHaystack) )
     279                 :         {
     280           54456 :             if( EQUALN(pszHaystack,s,nTargetLen) )
     281            1846 :                 return nPos;
     282                 :         }
     283                 : 
     284          881684 :         nPos++;
     285          881684 :         pszHaystack++;
     286                 :     }
     287                 : 
     288           25484 :     return std::string::npos;
     289                 : }
     290                 : 
     291                 : /************************************************************************/
     292                 : /*                              toupper()                               */
     293                 : /************************************************************************/
     294                 : 
     295                 : /**
     296                 :  * Convert to upper case in place.
     297                 :  */
     298                 : 
     299               0 : CPLString &CPLString::toupper()
     300                 : 
     301                 : {
     302                 :     size_t i;
     303                 : 
     304               0 :     for( i = 0; i < size(); i++ )
     305               0 :         (*this)[i] = (char) ::toupper( (*this)[i] );
     306                 : 
     307               0 :     return *this;
     308                 : }
     309                 : 
     310                 : /************************************************************************/
     311                 : /*                              tolower()                               */
     312                 : /************************************************************************/
     313                 : 
     314                 : /**
     315                 :  * Convert to lower case in place.
     316                 :  */
     317                 : 
     318            8042 : CPLString &CPLString::tolower()
     319                 : 
     320                 : {
     321                 :     size_t i;
     322                 : 
     323           55030 :     for( i = 0; i < size(); i++ )
     324           46988 :         (*this)[i] = (char) ::tolower( (*this)[i] );
     325                 : 
     326            8042 :     return *this;
     327                 : }
     328                 : 
     329                 : /************************************************************************/
     330                 : /*                         CPLURLGetValue()                             */
     331                 : /************************************************************************/
     332                 : 
     333                 : /**
     334                 :  * Return the value matching a key from a key=value pair in a URL.
     335                 :  *
     336                 :  * @param pszURL the URL.
     337                 :  * @param pszKey the key to find.
     338                 :  * @return the value of empty string if not found.
     339                 :  * @since GDAL 1.9.0
     340                 :  */
     341             744 : CPLString CPLURLGetValue(const char* pszURL, const char* pszKey)
     342                 : {
     343             744 :     CPLString osKey(pszKey);
     344             744 :     osKey += "=";
     345             744 :     size_t nKeyPos = CPLString(pszURL).ifind(osKey);
     346             776 :     if (nKeyPos != std::string::npos && nKeyPos > 0 &&
     347              32 :         (pszURL[nKeyPos-1] == '?' || pszURL[nKeyPos-1] == '&'))
     348                 :     {
     349              20 :         CPLString osValue(pszURL + nKeyPos + strlen(osKey));
     350              20 :         const char* pszValue = osValue.c_str();
     351              20 :         const char* pszSep = strchr(pszValue, '&');
     352              20 :         if (pszSep)
     353                 :         {
     354              16 :             osValue.resize(pszSep - pszValue);
     355                 :         }
     356              20 :         return osValue;
     357                 :     }
     358             724 :     return "";
     359                 : }
     360                 : 
     361                 : /************************************************************************/
     362                 : /*                          CPLURLAddKVP()                              */
     363                 : /************************************************************************/
     364                 : 
     365                 : /**
     366                 :  * Return a new URL with a new key=value pair.
     367                 :  *
     368                 :  * @param pszURL the URL.
     369                 :  * @param pszKey the key to find.
     370                 :  * @param pszValue the value of the key (may be NULL to unset an existing KVP).
     371                 :  * @return the modified URL.
     372                 :  * @since GDAL 1.9.0
     373                 :  */
     374             556 : CPLString CPLURLAddKVP(const char* pszURL, const char* pszKey,
     375                 :                        const char* pszValue)
     376                 : {
     377             556 :     CPLString osURL(pszURL);
     378             556 :     if (strchr(osURL, '?') == NULL)
     379              24 :         osURL += "?";
     380             556 :     pszURL = osURL.c_str();
     381                 : 
     382             556 :     CPLString osKey(pszKey);
     383             556 :     osKey += "=";
     384             556 :     size_t nKeyPos = osURL.ifind(osKey);
     385             604 :     if (nKeyPos != std::string::npos && nKeyPos > 0 &&
     386              48 :         (pszURL[nKeyPos-1] == '?' || pszURL[nKeyPos-1] == '&'))
     387                 :     {
     388              34 :         CPLString osNewURL(osURL);
     389              34 :         osNewURL.resize(nKeyPos);
     390              34 :         if (pszValue)
     391                 :         {
     392               6 :             osNewURL += osKey;
     393               6 :             osNewURL += pszValue;
     394                 :         }
     395              34 :         const char* pszNext = strchr(pszURL + nKeyPos, '&');
     396              34 :         if (pszNext)
     397                 :         {
     398              32 :             if (osNewURL[osNewURL.size()-1] == '&'
     399                 :                 || osNewURL[osNewURL.size()-1] == '?' )
     400              26 :                 osNewURL += pszNext + 1;
     401                 :             else
     402               6 :                 osNewURL += pszNext;
     403                 :         }
     404              34 :         return osNewURL;
     405                 :     }
     406                 :     else
     407                 :     {
     408             522 :         if (pszValue)
     409                 :         {
     410             314 :             if (osURL[osURL.size()-1] != '&' && osURL[osURL.size()-1] != '?')
     411             290 :                 osURL += '&';
     412             314 :             osURL += osKey;
     413             314 :             osURL += pszValue;
     414                 :         }
     415             522 :         return osURL;
     416               0 :     }
     417                 : }

Generated by: LCOV version 1.7