1 : /******************************************************************************
2 : * $Id: cplstring.cpp 11044 2007-03-22 12:04:04Z dron $
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 11044 2007-03-22 12:04:04Z dron $");
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 41684 : CPLString &CPLString::Printf( const char *pszFormat, ... )
46 :
47 : {
48 : va_list args;
49 :
50 41684 : va_start( args, pszFormat );
51 41684 : vPrintf( pszFormat, args );
52 41684 : va_end( args );
53 :
54 41684 : return *this;
55 : }
56 :
57 : /************************************************************************/
58 : /* vPrintf() */
59 : /************************************************************************/
60 :
61 45571 : 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 45571 : va_copy( wrk_args, args );
90 : #else
91 : wrk_args = args;
92 : #endif
93 :
94 : nPR = vsnprintf( szModestBuffer, sizeof(szModestBuffer), pszFormat,
95 45571 : wrk_args );
96 46045 : if( nPR == -1 || nPR >= (int) sizeof(szModestBuffer)-1 )
97 : {
98 474 : int nWorkBufferSize = 2000;
99 474 : char *pszWorkBuffer = (char *) CPLMalloc(nWorkBufferSize);
100 :
101 : #ifdef va_copy
102 474 : va_end( wrk_args );
103 474 : va_copy( wrk_args, args );
104 : #else
105 : wrk_args = args;
106 : #endif
107 970 : while( (nPR=vsnprintf( pszWorkBuffer, nWorkBufferSize, pszFormat,wrk_args))
108 : >= nWorkBufferSize-1
109 : || nPR == -1 )
110 : {
111 22 : nWorkBufferSize *= 4;
112 : pszWorkBuffer = (char *) CPLRealloc(pszWorkBuffer,
113 22 : nWorkBufferSize );
114 : #ifdef va_copy
115 22 : va_end( wrk_args );
116 22 : va_copy( wrk_args, args );
117 : #else
118 : wrk_args = args;
119 : #endif
120 : }
121 474 : *this = pszWorkBuffer;
122 474 : CPLFree( pszWorkBuffer );
123 : }
124 : else
125 : {
126 45097 : *this = szModestBuffer;
127 : }
128 45571 : va_end( wrk_args );
129 : #endif
130 :
131 45571 : 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 0 : CPLString &CPLString::FormatC( double dfValue, const char *pszFormat )
153 :
154 : {
155 0 : if( pszFormat == NULL )
156 0 : pszFormat = "%g";
157 :
158 : char szWork[512]; // presumably long enough for any number?
159 :
160 0 : sprintf( szWork, pszFormat, dfValue );
161 : CPLAssert( strlen(szWork) < sizeof(szWork) );
162 :
163 0 : if( strchr( szWork, ',' ) != NULL )
164 : {
165 0 : char *pszDelim = strchr( szWork, ',' );
166 0 : *pszDelim = '.';
167 : }
168 :
169 0 : *this += szWork;
170 :
171 0 : 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 15426 : CPLString &CPLString::Trim()
188 :
189 : {
190 : size_t iLeft, iRight;
191 : static const char szWhitespace[] = " \t\r\n";
192 :
193 15426 : iLeft = find_first_not_of( szWhitespace );
194 15426 : iRight = find_last_not_of( szWhitespace );
195 :
196 15426 : if( iLeft == std::string::npos )
197 : {
198 3438 : erase();
199 3438 : return *this;
200 : }
201 :
202 11988 : assign( substr( iLeft, iRight - iLeft + 1 ) );
203 :
204 11988 : return *this;
205 : }
|