1 /********************************************************************** 2 * $Id: cpl_string.h 28025 2014-11-28 00:01:32Z rouault $ 3 * 4 * Name: cpl_string.h 5 * Project: CPL - Common Portability Library 6 * Purpose: String and StringList functions. 7 * Author: Daniel Morissette, dmorissette@mapgears.com 8 * 9 ********************************************************************** 10 * Copyright (c) 1998, Daniel Morissette 11 * Copyright (c) 2008-2014, Even Rouault <even dot rouault at mines-paris dot org> 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining a 14 * copy of this software and associated documentation files (the "Software"), 15 * to deal in the Software without restriction, including without limitation 16 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 17 * and/or sell copies of the Software, and to permit persons to whom the 18 * Software is furnished to do so, subject to the following conditions: 19 * 20 * The above copyright notice and this permission notice shall be included 21 * in all copies or substantial portions of the Software. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 26 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 28 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 29 * DEALINGS IN THE SOFTWARE. 30 ****************************************************************************/ 31 32 #ifndef _CPL_STRING_H_INCLUDED 33 #define _CPL_STRING_H_INCLUDED 34 35 #include "cpl_vsi.h" 36 #include "cpl_error.h" 37 #include "cpl_conv.h" 38 39 /** 40 * \file cpl_string.h 41 * 42 * Various convenience functions for working with strings and string lists. 43 * 44 * A StringList is just an array of strings with the last pointer being 45 * NULL. An empty StringList may be either a NULL pointer, or a pointer to 46 * a pointer memory location with a NULL value. 47 * 48 * A common convention for StringLists is to use them to store name/value 49 * lists. In this case the contents are treated like a dictionary of 50 * name/value pairs. The actual data is formatted with each string having 51 * the format "<name>:<value>" (though "=" is also an acceptable separator). 52 * A number of the functions in the file operate on name/value style 53 * string lists (such as CSLSetNameValue(), and CSLFetchNameValue()). 54 * 55 * To some extent the CPLStringList C++ class can be used to abstract 56 * managing string lists a bit but still be able to return them from C 57 * functions. 58 * 59 */ 60 61 CPL_C_START 62 63 char CPL_DLL **CSLAddString(char **papszStrList, const char *pszNewString) CPL_WARN_UNUSED_RESULT; 64 int CPL_DLL CSLCount(char **papszStrList); 65 const char CPL_DLL *CSLGetField( char **, int ); 66 void CPL_DLL CPL_STDCALL CSLDestroy(char **papszStrList); 67 char CPL_DLL **CSLDuplicate(char **papszStrList) CPL_WARN_UNUSED_RESULT; 68 char CPL_DLL **CSLMerge( char **papszOrig, char **papszOverride ) CPL_WARN_UNUSED_RESULT; 69 70 char CPL_DLL **CSLTokenizeString(const char *pszString ) CPL_WARN_UNUSED_RESULT; 71 char CPL_DLL **CSLTokenizeStringComplex(const char *pszString, 72 const char *pszDelimiter, 73 int bHonourStrings, int bAllowEmptyTokens ) CPL_WARN_UNUSED_RESULT; 74 char CPL_DLL **CSLTokenizeString2( const char *pszString, 75 const char *pszDelimeter, 76 int nCSLTFlags ) CPL_WARN_UNUSED_RESULT; 77 78 #define CSLT_HONOURSTRINGS 0x0001 79 #define CSLT_ALLOWEMPTYTOKENS 0x0002 80 #define CSLT_PRESERVEQUOTES 0x0004 81 #define CSLT_PRESERVEESCAPES 0x0008 82 #define CSLT_STRIPLEADSPACES 0x0010 83 #define CSLT_STRIPENDSPACES 0x0020 84 85 int CPL_DLL CSLPrint(char **papszStrList, FILE *fpOut); 86 char CPL_DLL **CSLLoad(const char *pszFname) CPL_WARN_UNUSED_RESULT; 87 char CPL_DLL **CSLLoad2(const char *pszFname, int nMaxLines, int nMaxCols, char** papszOptions) CPL_WARN_UNUSED_RESULT; 88 int CPL_DLL CSLSave(char **papszStrList, const char *pszFname); 89 90 char CPL_DLL **CSLInsertStrings(char **papszStrList, int nInsertAtLineNo, 91 char **papszNewLines) CPL_WARN_UNUSED_RESULT; 92 char CPL_DLL **CSLInsertString(char **papszStrList, int nInsertAtLineNo, 93 const char *pszNewLine) CPL_WARN_UNUSED_RESULT; 94 char CPL_DLL **CSLRemoveStrings(char **papszStrList, int nFirstLineToDelete, 95 int nNumToRemove, char ***ppapszRetStrings) CPL_WARN_UNUSED_RESULT; 96 int CPL_DLL CSLFindString( char **, const char * ); 97 int CPL_DLL CSLFindStringCaseSensitive( char **, const char * ); 98 int CPL_DLL CSLPartialFindString( char **papszHaystack, 99 const char * pszNeedle ); 100 int CPL_DLL CSLFindName(char **papszStrList, const char *pszName); 101 int CPL_DLL CSLTestBoolean( const char *pszValue ); 102 int CPL_DLL CSLFetchBoolean( char **papszStrList, const char *pszKey, 103 int bDefault ); 104 105 const char CPL_DLL * 106 CPLParseNameValue(const char *pszNameValue, char **ppszKey ); 107 const char CPL_DLL * 108 CSLFetchNameValue(char **papszStrList, const char *pszName); 109 const char CPL_DLL * 110 CSLFetchNameValueDef(char **papszStrList, const char *pszName, 111 const char *pszDefault ); 112 char CPL_DLL ** 113 CSLFetchNameValueMultiple(char **papszStrList, const char *pszName); 114 char CPL_DLL ** 115 CSLAddNameValue(char **papszStrList, 116 const char *pszName, const char *pszValue) CPL_WARN_UNUSED_RESULT; 117 char CPL_DLL ** 118 CSLSetNameValue(char **papszStrList, 119 const char *pszName, const char *pszValue) CPL_WARN_UNUSED_RESULT; 120 void CPL_DLL CSLSetNameValueSeparator( char ** papszStrList, 121 const char *pszSeparator ); 122 123 #define CPLES_BackslashQuotable 0 124 #define CPLES_XML 1 125 #define CPLES_URL 2 126 #define CPLES_SQL 3 127 #define CPLES_CSV 4 128 #define CPLES_XML_BUT_QUOTES 5 129 130 char CPL_DLL *CPLEscapeString( const char *pszString, int nLength, 131 int nScheme ) CPL_WARN_UNUSED_RESULT; 132 char CPL_DLL *CPLUnescapeString( const char *pszString, int *pnLength, 133 int nScheme ) CPL_WARN_UNUSED_RESULT; 134 135 char CPL_DLL *CPLBinaryToHex( int nBytes, const GByte *pabyData ) CPL_WARN_UNUSED_RESULT; 136 GByte CPL_DLL *CPLHexToBinary( const char *pszHex, int *pnBytes ) CPL_WARN_UNUSED_RESULT; 137 138 char CPL_DLL *CPLBase64Encode( int nBytes, const GByte *pabyData ) CPL_WARN_UNUSED_RESULT; 139 int CPL_DLL CPLBase64DecodeInPlace(GByte* pszBase64); 140 141 typedef enum 142 { 143 CPL_VALUE_STRING, 144 CPL_VALUE_REAL, 145 CPL_VALUE_INTEGER 146 } CPLValueType; 147 148 CPLValueType CPL_DLL CPLGetValueType(const char* pszValue); 149 150 size_t CPL_DLL CPLStrlcpy(char* pszDest, const char* pszSrc, size_t nDestSize); 151 size_t CPL_DLL CPLStrlcat(char* pszDest, const char* pszSrc, size_t nDestSize); 152 size_t CPL_DLL CPLStrnlen (const char *pszStr, size_t nMaxLen); 153 154 /* -------------------------------------------------------------------- */ 155 /* Locale independant formatting functions. */ 156 /* -------------------------------------------------------------------- */ 157 int CPL_DLL CPLvsnprintf(char *str, size_t size, const char* fmt, va_list args); 158 int CPL_DLL CPLsnprintf(char *str, size_t size, const char* fmt, ...) CPL_PRINT_FUNC_FORMAT(3,4); 159 int CPL_DLL CPLsprintf(char *str, const char* fmt, ...) CPL_PRINT_FUNC_FORMAT(2, 3); 160 int CPL_DLL CPLprintf(const char* fmt, ...) CPL_PRINT_FUNC_FORMAT(1, 2); 161 int CPL_DLL CPLsscanf(const char* str, const char* fmt, ...); /* caution: only works with limited number of formats */ 162 163 const char CPL_DLL *CPLSPrintf(const char *fmt, ...) CPL_PRINT_FUNC_FORMAT(1, 2); 164 char CPL_DLL **CSLAppendPrintf(char **papszStrList, const char *fmt, ...) CPL_PRINT_FUNC_FORMAT(2, 3) CPL_WARN_UNUSED_RESULT; 165 int CPL_DLL CPLVASPrintf(char **buf, const char *fmt, va_list args ); 166 167 /* -------------------------------------------------------------------- */ 168 /* RFC 23 character set conversion/recoding API (cpl_recode.cpp). */ 169 /* -------------------------------------------------------------------- */ 170 #define CPL_ENC_LOCALE "" 171 #define CPL_ENC_UTF8 "UTF-8" 172 #define CPL_ENC_UTF16 "UTF-16" 173 #define CPL_ENC_UCS2 "UCS-2" 174 #define CPL_ENC_UCS4 "UCS-4" 175 #define CPL_ENC_ASCII "ASCII" 176 #define CPL_ENC_ISO8859_1 "ISO-8859-1" 177 178 int CPL_DLL CPLEncodingCharSize( const char *pszEncoding ); 179 void CPL_DLL CPLClearRecodeWarningFlags( void ); 180 char CPL_DLL *CPLRecode( const char *pszSource, 181 const char *pszSrcEncoding, 182 const char *pszDstEncoding ) CPL_WARN_UNUSED_RESULT; 183 char CPL_DLL *CPLRecodeFromWChar( const wchar_t *pwszSource, 184 const char *pszSrcEncoding, 185 const char *pszDstEncoding ) CPL_WARN_UNUSED_RESULT; 186 wchar_t CPL_DLL *CPLRecodeToWChar( const char *pszSource, 187 const char *pszSrcEncoding, 188 const char *pszDstEncoding ) CPL_WARN_UNUSED_RESULT; 189 int CPL_DLL CPLIsUTF8(const char* pabyData, int nLen); 190 char CPL_DLL *CPLForceToASCII(const char* pabyData, int nLen, char chReplacementChar) CPL_WARN_UNUSED_RESULT; 191 int CPL_DLL CPLStrlenUTF8(const char *pszUTF8Str); 192 193 CPL_C_END 194 195 /************************************************************************/ 196 /* CPLString */ 197 /************************************************************************/ 198 199 #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS) 200 201 #include <string> 202 203 /* 204 * Simple trick to avoid "using" declaration in header for new compilers 205 * but make it still working with old compilers which throw C2614 errors. 206 * 207 * Define MSVC_OLD_STUPID_BEHAVIOUR 208 * for old compilers: VC++ 5 and 6 as well as eVC++ 3 and 4. 209 */ 210 211 /* 212 * Detect old MSVC++ compiler <= 6.0 213 * 1200 - VC++ 6.0 214 * 1200-1202 - eVC++ 4.0 215 */ 216 #if defined(_MSC_VER) 217 # if (_MSC_VER <= 1202) 218 # define MSVC_OLD_STUPID_BEHAVIOUR 219 # endif 220 #endif 221 222 /* Avoid C2614 errors */ 223 #ifdef MSVC_OLD_STUPID_BEHAVIOUR 224 using std::string; 225 # define gdal_std_string string 226 #else 227 # define gdal_std_string std::string 228 #endif 229 230 /* Remove annoying warnings in Microsoft eVC++ and Microsoft Visual C++ */ 231 #if defined(WIN32CE) 232 # pragma warning(disable:4251 4275 4786) 233 #endif 234 235 //! Convenient string class based on std::string. 236 class CPL_DLL CPLString : public gdal_std_string 237 { 238 public: 239 240 CPLString(void)241 CPLString(void) {} CPLString(const std::string & oStr)242 CPLString( const std::string &oStr ) : gdal_std_string( oStr ) {} CPLString(const char * pszStr)243 CPLString( const char *pszStr ) : gdal_std_string( pszStr ) {} 244 245 operator const char* (void) const { return c_str(); } 246 247 char& operator[](std::string::size_type i) 248 { 249 return gdal_std_string::operator[](i); 250 } 251 252 const char& operator[](std::string::size_type i) const 253 { 254 return gdal_std_string::operator[](i); 255 } 256 257 char& operator[](int i) 258 { 259 return gdal_std_string::operator[](static_cast<std::string::size_type>(i)); 260 } 261 262 const char& operator[](int i) const 263 { 264 return gdal_std_string::operator[](static_cast<std::string::size_type>(i)); 265 } 266 Clear()267 void Clear() { resize(0); } 268 269 // NULL safe assign and free. Seize(char * pszValue)270 void Seize(char *pszValue) 271 { 272 if (pszValue == NULL ) 273 Clear(); 274 else 275 { 276 *this = pszValue; 277 CPLFree(pszValue); 278 } 279 } 280 281 /* There seems to be a bug in the way the compiler count indices... Should be CPL_PRINT_FUNC_FORMAT (1, 2) */ 282 CPLString &Printf( const char *pszFormat, ... ) CPL_PRINT_FUNC_FORMAT (2, 3); 283 CPLString &vPrintf( const char *pszFormat, va_list args ); 284 CPLString &FormatC( double dfValue, const char *pszFormat = NULL ); 285 CPLString &Trim(); 286 CPLString &Recode( const char *pszSrcEncoding, const char *pszDstEncoding ); 287 288 /* case insensitive find alternates */ 289 size_t ifind( const std::string & str, size_t pos = 0 ) const; 290 size_t ifind( const char * s, size_t pos = 0 ) const; 291 CPLString &toupper( void ); 292 CPLString &tolower( void ); 293 }; 294 295 CPLString CPLOPrintf(const char *pszFormat, ... ) CPL_PRINT_FUNC_FORMAT (1, 2); 296 CPLString CPLOvPrintf(const char *pszFormat, va_list args); 297 298 /* -------------------------------------------------------------------- */ 299 /* URL processing functions, here since they depend on CPLString. */ 300 /* -------------------------------------------------------------------- */ 301 CPLString CPL_DLL CPLURLGetValue(const char* pszURL, const char* pszKey); 302 CPLString CPL_DLL CPLURLAddKVP(const char* pszURL, const char* pszKey, 303 const char* pszValue); 304 305 /************************************************************************/ 306 /* CPLStringList */ 307 /************************************************************************/ 308 309 //! String list class designed around our use of C "char**" string lists. 310 class CPL_DLL CPLStringList 311 { 312 char **papszList; 313 mutable int nCount; 314 mutable int nAllocation; 315 int bOwnList; 316 int bIsSorted; 317 318 void Initialize(); 319 void MakeOurOwnCopy(); 320 void EnsureAllocation( int nMaxLength ); 321 int FindSortedInsertionPoint( const char *pszLine ); 322 323 public: 324 CPLStringList(); 325 CPLStringList( char **papszList, int bTakeOwnership=TRUE ); 326 CPLStringList( const CPLStringList& oOther ); 327 ~CPLStringList(); 328 329 CPLStringList &Clear(); 330 size()331 int size() const { return Count(); } 332 int Count() const; 333 334 CPLStringList &AddString( const char *pszNewString ); 335 CPLStringList &AddStringDirectly( char *pszNewString ); 336 InsertString(int nInsertAtLineNo,const char * pszNewLine)337 CPLStringList &InsertString( int nInsertAtLineNo, const char *pszNewLine ) 338 { return InsertStringDirectly( nInsertAtLineNo, CPLStrdup(pszNewLine) ); } 339 CPLStringList &InsertStringDirectly( int nInsertAtLineNo, char *pszNewLine); 340 341 // CPLStringList &InsertStrings( int nInsertAtLineNo, char **papszNewLines ); 342 // CPLStringList &RemoveStrings( int nFirstLineToDelete, int nNumToRemove=1 ); 343 FindString(const char * pszTarget)344 int FindString( const char *pszTarget ) const 345 { return CSLFindString( papszList, pszTarget ); } PartialFindString(const char * pszNeedle)346 int PartialFindString( const char *pszNeedle ) const 347 { return CSLPartialFindString( papszList, pszNeedle ); } 348 349 int FindName( const char *pszName ) const; 350 int FetchBoolean( const char *pszKey, int bDefault ) const; 351 const char *FetchNameValue( const char *pszKey ) const; 352 const char *FetchNameValueDef( const char *pszKey, const char *pszDefault ) const; 353 CPLStringList &AddNameValue( const char *pszKey, const char *pszValue ); 354 CPLStringList &SetNameValue( const char *pszKey, const char *pszValue ); 355 356 CPLStringList &Assign( char **papszListIn, int bTakeOwnership=TRUE ); 357 CPLStringList &operator=(char **papszListIn) { return Assign( papszListIn, TRUE ); } 358 CPLStringList &operator=(const CPLStringList& oOther); 359 360 char * operator[](int i); 361 char * operator[](size_t i) { return (*this)[(int)i]; } 362 const char * operator[](int i) const; 363 const char * operator[](size_t i) const { return (*this)[(int)i]; } 364 List()365 char **List() { return papszList; } 366 char **StealList(); 367 368 CPLStringList &Sort(); IsSorted()369 int IsSorted() const { return bIsSorted; } 370 371 operator char**(void) { return List(); } 372 }; 373 374 #endif /* def __cplusplus && !CPL_SUPRESS_CPLUSPLUS */ 375 376 #endif /* _CPL_STRING_H_INCLUDED */ 377