Line data Source code
1 : /**********************************************************************
2 : * $Id$
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 spatialys.com>
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_error.h"
36 : #include "cpl_conv.h"
37 : #include "cpl_vsi.h"
38 :
39 : #include <stdbool.h>
40 :
41 : /**
42 : * \file cpl_string.h
43 : *
44 : * Various convenience functions for working with strings and string lists.
45 : *
46 : * A StringList is just an array of strings with the last pointer being
47 : * NULL. An empty StringList may be either a NULL pointer, or a pointer to
48 : * a pointer memory location with a NULL value.
49 : *
50 : * A common convention for StringLists is to use them to store name/value
51 : * lists. In this case the contents are treated like a dictionary of
52 : * name/value pairs. The actual data is formatted with each string having
53 : * the format "<name>:<value>" (though "=" is also an acceptable separator).
54 : * A number of the functions in the file operate on name/value style
55 : * string lists (such as CSLSetNameValue(), and CSLFetchNameValue()).
56 : *
57 : * To some extent the CPLStringList C++ class can be used to abstract
58 : * managing string lists a bit but still be able to return them from C
59 : * functions.
60 : *
61 : */
62 :
63 : CPL_C_START
64 :
65 : char CPL_DLL **CSLAddString(char **papszStrList,
66 : const char *pszNewString) CPL_WARN_UNUSED_RESULT;
67 : char CPL_DLL **
68 : CSLAddStringMayFail(char **papszStrList,
69 : const char *pszNewString) CPL_WARN_UNUSED_RESULT;
70 : int CPL_DLL CSLCount(CSLConstList papszStrList);
71 : const char CPL_DLL *CSLGetField(CSLConstList, int);
72 : void CPL_DLL CPL_STDCALL CSLDestroy(char **papszStrList);
73 : char CPL_DLL **CSLDuplicate(CSLConstList papszStrList) CPL_WARN_UNUSED_RESULT;
74 : char CPL_DLL **CSLMerge(char **papszOrig,
75 : CSLConstList papszOverride) CPL_WARN_UNUSED_RESULT;
76 :
77 : char CPL_DLL **CSLTokenizeString(const char *pszString) CPL_WARN_UNUSED_RESULT;
78 : char CPL_DLL **
79 : CSLTokenizeStringComplex(const char *pszString, const char *pszDelimiter,
80 : int bHonourStrings,
81 : int bAllowEmptyTokens) CPL_WARN_UNUSED_RESULT;
82 : char CPL_DLL **CSLTokenizeString2(const char *pszString,
83 : const char *pszDelimiter,
84 : int nCSLTFlags) CPL_WARN_UNUSED_RESULT;
85 :
86 : /** Flag for CSLTokenizeString2() to honour strings */
87 : #define CSLT_HONOURSTRINGS 0x0001
88 : /** Flag for CSLTokenizeString2() to allow empty tokens */
89 : #define CSLT_ALLOWEMPTYTOKENS 0x0002
90 : /** Flag for CSLTokenizeString2() to preserve quotes */
91 : #define CSLT_PRESERVEQUOTES 0x0004
92 : /** Flag for CSLTokenizeString2() to preserve escape characters */
93 : #define CSLT_PRESERVEESCAPES 0x0008
94 : /** Flag for CSLTokenizeString2() to strip leading spaces */
95 : #define CSLT_STRIPLEADSPACES 0x0010
96 : /** Flag for CSLTokenizeString2() to strip trailaing spaces */
97 : #define CSLT_STRIPENDSPACES 0x0020
98 :
99 : int CPL_DLL CSLPrint(CSLConstList papszStrList, FILE *fpOut);
100 : char CPL_DLL **CSLLoad(const char *pszFname) CPL_WARN_UNUSED_RESULT;
101 : char CPL_DLL **CSLLoad2(const char *pszFname, int nMaxLines, int nMaxCols,
102 : CSLConstList papszOptions) CPL_WARN_UNUSED_RESULT;
103 : int CPL_DLL CSLSave(CSLConstList papszStrList, const char *pszFname);
104 :
105 : char CPL_DLL **
106 : CSLInsertStrings(char **papszStrList, int nInsertAtLineNo,
107 : CSLConstList papszNewLines) CPL_WARN_UNUSED_RESULT;
108 : char CPL_DLL **CSLInsertString(char **papszStrList, int nInsertAtLineNo,
109 : const char *pszNewLine) CPL_WARN_UNUSED_RESULT;
110 : char CPL_DLL **
111 : CSLRemoveStrings(char **papszStrList, int nFirstLineToDelete, int nNumToRemove,
112 : char ***ppapszRetStrings) CPL_WARN_UNUSED_RESULT;
113 : int CPL_DLL CSLFindString(CSLConstList papszList, const char *pszTarget);
114 : int CPL_DLL CSLFindStringCaseSensitive(CSLConstList papszList,
115 : const char *pszTarget);
116 : int CPL_DLL CSLPartialFindString(CSLConstList papszHaystack,
117 : const char *pszNeedle);
118 : int CPL_DLL CSLFindName(CSLConstList papszStrList, const char *pszName);
119 : int CPL_DLL CSLFetchBoolean(CSLConstList papszStrList, const char *pszKey,
120 : int bDefault);
121 :
122 : /* TODO: Deprecate CSLTestBoolean. Remove in GDAL 3.x. */
123 : int CPL_DLL CSLTestBoolean(const char *pszValue);
124 : /* Do not use CPLTestBoolean in C++ code. Use CPLTestBool. */
125 : int CPL_DLL CPLTestBoolean(const char *pszValue);
126 :
127 : bool CPL_DLL CPLTestBool(const char *pszValue);
128 : bool CPL_DLL CPLFetchBool(CSLConstList papszStrList, const char *pszKey,
129 : bool bDefault);
130 :
131 : const char CPL_DLL *CPLParseNameValue(const char *pszNameValue, char **ppszKey);
132 : const char CPL_DLL *CPLParseNameValueSep(const char *pszNameValue,
133 : char **ppszKey, char chSep);
134 :
135 : const char CPL_DLL *CSLFetchNameValue(CSLConstList papszStrList,
136 : const char *pszName);
137 : const char CPL_DLL *CSLFetchNameValueDef(CSLConstList papszStrList,
138 : const char *pszName,
139 : const char *pszDefault);
140 : char CPL_DLL **CSLFetchNameValueMultiple(CSLConstList papszStrList,
141 : const char *pszName);
142 : char CPL_DLL **CSLAddNameValue(char **papszStrList, const char *pszName,
143 : const char *pszValue) CPL_WARN_UNUSED_RESULT;
144 : char CPL_DLL **CSLSetNameValue(char **papszStrList, const char *pszName,
145 : const char *pszValue) CPL_WARN_UNUSED_RESULT;
146 : void CPL_DLL CSLSetNameValueSeparator(char **papszStrList,
147 : const char *pszSeparator);
148 :
149 : char CPL_DLL **CSLParseCommandLine(const char *pszCommandLine);
150 :
151 : /** Scheme for CPLEscapeString()/CPLUnescapeString() for backlash quoting */
152 : #define CPLES_BackslashQuotable 0
153 : /** Scheme for CPLEscapeString()/CPLUnescapeString() for XML */
154 : #define CPLES_XML 1
155 : /** Scheme for CPLEscapeString()/CPLUnescapeString() for URL */
156 : #define CPLES_URL 2
157 : /** Scheme for CPLEscapeString()/CPLUnescapeString() for SQL */
158 : #define CPLES_SQL 3
159 : /** Scheme for CPLEscapeString()/CPLUnescapeString() for CSV */
160 : #define CPLES_CSV 4
161 : /** Scheme for CPLEscapeString()/CPLUnescapeString() for XML (preserves quotes)
162 : */
163 : #define CPLES_XML_BUT_QUOTES 5
164 : /** Scheme for CPLEscapeString()/CPLUnescapeString() for CSV (forced quoting) */
165 : #define CPLES_CSV_FORCE_QUOTING 6
166 : /** Scheme for CPLEscapeString()/CPLUnescapeString() for SQL identifiers */
167 : #define CPLES_SQLI 7
168 :
169 : char CPL_DLL *CPLEscapeString(const char *pszString, int nLength,
170 : int nScheme) CPL_WARN_UNUSED_RESULT;
171 : char CPL_DLL *CPLUnescapeString(const char *pszString, int *pnLength,
172 : int nScheme) CPL_WARN_UNUSED_RESULT;
173 :
174 : char CPL_DLL *CPLBinaryToHex(int nBytes,
175 : const GByte *pabyData) CPL_WARN_UNUSED_RESULT;
176 : GByte CPL_DLL *CPLHexToBinary(const char *pszHex,
177 : int *pnBytes) CPL_WARN_UNUSED_RESULT;
178 :
179 : char CPL_DLL *CPLBase64Encode(int nBytes,
180 : const GByte *pabyData) CPL_WARN_UNUSED_RESULT;
181 : int CPL_DLL CPLBase64DecodeInPlace(GByte *pszBase64) CPL_WARN_UNUSED_RESULT;
182 :
183 : /** Type of value */
184 : typedef enum
185 : {
186 : CPL_VALUE_STRING, /**< String */
187 : CPL_VALUE_REAL, /**< Real number */
188 : CPL_VALUE_INTEGER /**< Integer */
189 : } CPLValueType;
190 :
191 : CPLValueType CPL_DLL CPLGetValueType(const char *pszValue);
192 :
193 : int CPL_DLL CPLToupper(int c);
194 : int CPL_DLL CPLTolower(int c);
195 :
196 : size_t CPL_DLL CPLStrlcpy(char *pszDest, const char *pszSrc, size_t nDestSize);
197 : size_t CPL_DLL CPLStrlcat(char *pszDest, const char *pszSrc, size_t nDestSize);
198 : size_t CPL_DLL CPLStrnlen(const char *pszStr, size_t nMaxLen);
199 :
200 : /* -------------------------------------------------------------------- */
201 : /* Locale independent formatting functions. */
202 : /* -------------------------------------------------------------------- */
203 : int CPL_DLL CPLvsnprintf(char *str, size_t size,
204 : CPL_FORMAT_STRING(const char *fmt), va_list args)
205 : CPL_PRINT_FUNC_FORMAT(3, 0);
206 :
207 : /* ALIAS_CPLSNPRINTF_AS_SNPRINTF might be defined to enable GCC 7 */
208 : /* -Wformat-truncation= warnings, but shouldn't be set for normal use */
209 : #if defined(ALIAS_CPLSNPRINTF_AS_SNPRINTF)
210 : #define CPLsnprintf snprintf
211 : #else
212 : int CPL_DLL CPLsnprintf(char *str, size_t size,
213 : CPL_FORMAT_STRING(const char *fmt), ...)
214 : CPL_PRINT_FUNC_FORMAT(3, 4);
215 : #endif
216 :
217 : /*! @cond Doxygen_Suppress */
218 : #if defined(GDAL_COMPILATION) && !defined(DONT_DEPRECATE_SPRINTF)
219 : int CPL_DLL CPLsprintf(char *str, CPL_FORMAT_STRING(const char *fmt), ...)
220 : CPL_PRINT_FUNC_FORMAT(2, 3) CPL_WARN_DEPRECATED("Use CPLsnprintf instead");
221 : #else
222 : int CPL_DLL CPLsprintf(char *str, CPL_FORMAT_STRING(const char *fmt), ...)
223 : CPL_PRINT_FUNC_FORMAT(2, 3);
224 : #endif
225 : /*! @endcond */
226 : int CPL_DLL CPLprintf(CPL_FORMAT_STRING(const char *fmt), ...)
227 : CPL_PRINT_FUNC_FORMAT(1, 2);
228 :
229 : /* For some reason Doxygen_Suppress is needed to avoid warning. Not sure why */
230 : /*! @cond Doxygen_Suppress */
231 : /* caution: only works with limited number of formats */
232 : int CPL_DLL CPLsscanf(const char *str, CPL_SCANF_FORMAT_STRING(const char *fmt),
233 : ...) CPL_SCAN_FUNC_FORMAT(2, 3);
234 : /*! @endcond */
235 :
236 : const char CPL_DLL *CPLSPrintf(CPL_FORMAT_STRING(const char *fmt), ...)
237 : CPL_PRINT_FUNC_FORMAT(1, 2) CPL_WARN_UNUSED_RESULT;
238 : char CPL_DLL **CSLAppendPrintf(char **papszStrList,
239 : CPL_FORMAT_STRING(const char *fmt), ...)
240 : CPL_PRINT_FUNC_FORMAT(2, 3) CPL_WARN_UNUSED_RESULT;
241 : int CPL_DLL CPLVASPrintf(char **buf, CPL_FORMAT_STRING(const char *fmt),
242 : va_list args) CPL_PRINT_FUNC_FORMAT(2, 0);
243 :
244 : /* -------------------------------------------------------------------- */
245 : /* RFC 23 character set conversion/recoding API (cpl_recode.cpp). */
246 : /* -------------------------------------------------------------------- */
247 : /** Encoding of the current locale */
248 : #define CPL_ENC_LOCALE ""
249 : /** UTF-8 encoding */
250 : #define CPL_ENC_UTF8 "UTF-8"
251 : /** UTF-16 encoding */
252 : #define CPL_ENC_UTF16 "UTF-16"
253 : /** UCS-2 encoding */
254 : #define CPL_ENC_UCS2 "UCS-2"
255 : /** UCS-4 encoding */
256 : #define CPL_ENC_UCS4 "UCS-4"
257 : /** ASCII encoding */
258 : #define CPL_ENC_ASCII "ASCII"
259 : /** ISO-8859-1 (LATIN1) encoding */
260 : #define CPL_ENC_ISO8859_1 "ISO-8859-1"
261 :
262 : int CPL_DLL CPLEncodingCharSize(const char *pszEncoding);
263 : /*! @cond Doxygen_Suppress */
264 : void CPL_DLL CPLClearRecodeWarningFlags(void);
265 : /*! @endcond */
266 : char CPL_DLL *CPLRecode(const char *pszSource, const char *pszSrcEncoding,
267 : const char *pszDstEncoding)
268 : CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
269 : char CPL_DLL *
270 : CPLRecodeFromWChar(const wchar_t *pwszSource, const char *pszSrcEncoding,
271 : const char *pszDstEncoding) CPL_WARN_UNUSED_RESULT;
272 : wchar_t CPL_DLL *
273 : CPLRecodeToWChar(const char *pszSource, const char *pszSrcEncoding,
274 : const char *pszDstEncoding) CPL_WARN_UNUSED_RESULT;
275 : int CPL_DLL CPLIsUTF8(const char *pabyData, int nLen);
276 : bool CPL_DLL CPLIsASCII(const char *pabyData, size_t nLen);
277 : char CPL_DLL *CPLForceToASCII(const char *pabyData, int nLen,
278 : char chReplacementChar) CPL_WARN_UNUSED_RESULT;
279 : char CPL_DLL *CPLUTF8ForceToASCII(const char *pszStr, char chReplacementChar)
280 : CPL_WARN_UNUSED_RESULT;
281 : int CPL_DLL CPLStrlenUTF8(const char *pszUTF8Str);
282 : int CPL_DLL CPLCanRecode(const char *pszTestStr, const char *pszSrcEncoding,
283 : const char *pszDstEncoding) CPL_WARN_UNUSED_RESULT;
284 : CPL_C_END
285 :
286 : /************************************************************************/
287 : /* CPLString */
288 : /************************************************************************/
289 :
290 : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
291 :
292 : extern "C++"
293 : {
294 : #ifndef DOXYGEN_SKIP
295 : #include <string>
296 : #include <vector>
297 : #endif
298 :
299 : // VC++ implicitly applies __declspec(dllexport) to template base classes
300 : // of classes marked with __declspec(dllexport).
301 : // Hence, if marked with CPL_DLL, VC++ would export symbols for the
302 : // specialization of std::basic_string<char>, since it is a base class of
303 : // CPLString. As a result, if an application linked both gdal.dll and a static
304 : // library that (implicitly) instantiates std::string (almost all do!), then the
305 : // linker would emit an error concerning duplicate symbols for std::string. The
306 : // least intrusive solution is to not mark the whole class with
307 : // __declspec(dllexport) for VC++, but only its non-inline methods.
308 : #ifdef _MSC_VER
309 : #define CPLSTRING_CLASS_DLL
310 : #define CPLSTRING_METHOD_DLL CPL_DLL
311 : #else
312 : /*! @cond Doxygen_Suppress */
313 : #define CPLSTRING_CLASS_DLL CPL_DLL
314 : #define CPLSTRING_METHOD_DLL
315 : /*! @endcond */
316 : #endif
317 :
318 : //! Convenient string class based on std::string.
319 20 : class CPLSTRING_CLASS_DLL CPLString : public std::string
320 : {
321 : public:
322 : /** Constructor */
323 14137964 : CPLString(void)
324 14137964 : {
325 14137644 : }
326 :
327 : /** Constructor */
328 : // cppcheck-suppress noExplicitConstructor
329 3814758 : CPLString(const std::string &oStr) : std::string(oStr)
330 : {
331 3814738 : }
332 :
333 : /** Constructor */
334 : // cppcheck-suppress noExplicitConstructor
335 6715727 : CPLString(const char *pszStr) : std::string(pszStr)
336 : {
337 6715707 : }
338 :
339 : /** Constructor */
340 56923 : CPLString(const char *pszStr, size_t n) : std::string(pszStr, n)
341 : {
342 56922 : }
343 :
344 : /** Return string as zero terminated character array */
345 22015376 : operator const char *(void) const
346 : {
347 22015376 : return c_str();
348 : }
349 :
350 : /** Return character at specified index */
351 43680125 : char &operator[](std::string::size_type i)
352 : {
353 43680125 : return std::string::operator[](i);
354 : }
355 :
356 : /** Return character at specified index */
357 203869 : const char &operator[](std::string::size_type i) const
358 : {
359 203869 : return std::string::operator[](i);
360 : }
361 :
362 : /** Return character at specified index */
363 112250 : char &operator[](int i)
364 : {
365 : return std::string::operator[](
366 112250 : static_cast<std::string::size_type>(i));
367 : }
368 :
369 : /** Return character at specified index */
370 19543 : const char &operator[](int i) const
371 : {
372 : return std::string::operator[](
373 19543 : static_cast<std::string::size_type>(i));
374 : }
375 :
376 : /** Clear the string */
377 23760 : void Clear()
378 : {
379 23760 : resize(0);
380 23760 : }
381 :
382 : /** Assign specified string and take ownership of it (assumed to be
383 : * allocated with CPLMalloc()). NULL can be safely passed to clear the
384 : * string. */
385 0 : void Seize(char *pszValue)
386 : {
387 0 : if (pszValue == nullptr)
388 0 : Clear();
389 : else
390 : {
391 0 : *this = pszValue;
392 0 : CPLFree(pszValue);
393 : }
394 0 : }
395 :
396 : /* There seems to be a bug in the way the compiler count indices...
397 : * Should be CPL_PRINT_FUNC_FORMAT (1, 2) */
398 : CPLSTRING_METHOD_DLL CPLString &
399 : Printf(CPL_FORMAT_STRING(const char *pszFormat), ...)
400 : CPL_PRINT_FUNC_FORMAT(2, 3);
401 : CPLSTRING_METHOD_DLL CPLString &
402 : vPrintf(CPL_FORMAT_STRING(const char *pszFormat), va_list args)
403 : CPL_PRINT_FUNC_FORMAT(2, 0);
404 : CPLSTRING_METHOD_DLL CPLString &
405 : FormatC(double dfValue, const char *pszFormat = nullptr);
406 : CPLSTRING_METHOD_DLL CPLString &Trim();
407 : CPLSTRING_METHOD_DLL CPLString &Recode(const char *pszSrcEncoding,
408 : const char *pszDstEncoding);
409 : CPLSTRING_METHOD_DLL CPLString &replaceAll(const std::string &osBefore,
410 : const std::string &osAfter);
411 : CPLSTRING_METHOD_DLL CPLString &replaceAll(const std::string &osBefore,
412 : char chAfter);
413 : CPLSTRING_METHOD_DLL CPLString &replaceAll(char chBefore,
414 : const std::string &osAfter);
415 : CPLSTRING_METHOD_DLL CPLString &replaceAll(char chBefore, char chAfter);
416 :
417 : /* case insensitive find alternates */
418 : CPLSTRING_METHOD_DLL size_t ifind(const std::string &str,
419 : size_t pos = 0) const;
420 : CPLSTRING_METHOD_DLL size_t ifind(const char *s, size_t pos = 0) const;
421 : CPLSTRING_METHOD_DLL CPLString &toupper(void);
422 : CPLSTRING_METHOD_DLL CPLString &tolower(void);
423 :
424 : CPLSTRING_METHOD_DLL bool endsWith(const std::string &osStr) const;
425 : };
426 :
427 : #undef CPLSTRING_CLASS_DLL
428 : #undef CPLSTRING_METHOD_DLL
429 :
430 : CPLString CPL_DLL CPLOPrintf(CPL_FORMAT_STRING(const char *pszFormat), ...)
431 : CPL_PRINT_FUNC_FORMAT(1, 2);
432 : CPLString CPL_DLL CPLOvPrintf(CPL_FORMAT_STRING(const char *pszFormat),
433 : va_list args) CPL_PRINT_FUNC_FORMAT(1, 0);
434 : CPLString CPL_DLL CPLQuotedSQLIdentifier(const char *pszIdent);
435 :
436 : /* -------------------------------------------------------------------- */
437 : /* URL processing functions, here since they depend on CPLString. */
438 : /* -------------------------------------------------------------------- */
439 : CPLString CPL_DLL CPLURLGetValue(const char *pszURL, const char *pszKey);
440 : CPLString CPL_DLL CPLURLAddKVP(const char *pszURL, const char *pszKey,
441 : const char *pszValue);
442 :
443 : /************************************************************************/
444 : /* CPLStringList */
445 : /************************************************************************/
446 :
447 : //! String list class designed around our use of C "char**" string lists.
448 5051640 : class CPL_DLL CPLStringList
449 : {
450 : char **papszList = nullptr;
451 : mutable int nCount = 0;
452 : mutable int nAllocation = 0;
453 : bool bOwnList = false;
454 : bool bIsSorted = false;
455 :
456 : bool MakeOurOwnCopy();
457 : bool EnsureAllocation(int nMaxLength);
458 : int FindSortedInsertionPoint(const char *pszLine);
459 :
460 : public:
461 : CPLStringList();
462 : explicit CPLStringList(char **papszList, int bTakeOwnership = TRUE);
463 : explicit CPLStringList(CSLConstList papszList);
464 : explicit CPLStringList(const std::vector<std::string> &aosList);
465 : explicit CPLStringList(std::initializer_list<const char *> oInitList);
466 : CPLStringList(const CPLStringList &oOther);
467 : CPLStringList(CPLStringList &&oOther);
468 : ~CPLStringList();
469 :
470 : static const CPLStringList BoundToConstList(CSLConstList papszList);
471 :
472 : CPLStringList &Clear();
473 :
474 : /** Clear the list */
475 0 : inline void clear()
476 : {
477 0 : Clear();
478 0 : }
479 :
480 : /** Return size of list */
481 732965 : int size() const
482 : {
483 732965 : return Count();
484 : }
485 :
486 : int Count() const;
487 :
488 : /** Return whether the list is empty. */
489 21830 : bool empty() const
490 : {
491 21830 : return Count() == 0;
492 : }
493 :
494 : CPLStringList &AddString(const char *pszNewString);
495 : CPLStringList &AddStringDirectly(char *pszNewString);
496 :
497 130 : CPLStringList &InsertString(int nInsertAtLineNo, const char *pszNewLine)
498 : {
499 130 : return InsertStringDirectly(nInsertAtLineNo, CPLStrdup(pszNewLine));
500 : }
501 :
502 : CPLStringList &InsertStringDirectly(int nInsertAtLineNo,
503 : char *pszNewLine);
504 :
505 : // CPLStringList &InsertStrings( int nInsertAtLineNo, char
506 : // **papszNewLines ); CPLStringList &RemoveStrings( int
507 : // nFirstLineToDelete, int nNumToRemove=1 );
508 :
509 : /** Return index of pszTarget in the list, or -1 */
510 15779 : int FindString(const char *pszTarget) const
511 : {
512 15779 : return CSLFindString(papszList, pszTarget);
513 : }
514 :
515 : /** Return index of pszTarget in the list (using partial search), or -1
516 : */
517 : int PartialFindString(const char *pszNeedle) const
518 : {
519 : return CSLPartialFindString(papszList, pszNeedle);
520 : }
521 :
522 : int FindName(const char *pszName) const;
523 : bool FetchBool(const char *pszKey, bool bDefault) const;
524 : // Deprecated.
525 : int FetchBoolean(const char *pszKey, int bDefault) const;
526 : const char *FetchNameValue(const char *pszKey) const;
527 : const char *FetchNameValueDef(const char *pszKey,
528 : const char *pszDefault) const;
529 : CPLStringList &AddNameValue(const char *pszKey, const char *pszValue);
530 : CPLStringList &SetNameValue(const char *pszKey, const char *pszValue);
531 :
532 : CPLStringList &Assign(char **papszListIn, int bTakeOwnership = TRUE);
533 :
534 : /** Assignment operator */
535 25904 : CPLStringList &operator=(char **papszListIn)
536 : {
537 25904 : return Assign(papszListIn, TRUE);
538 : }
539 :
540 : /** Assignment operator */
541 : CPLStringList &operator=(const CPLStringList &oOther);
542 : /** Assignment operator */
543 : CPLStringList &operator=(CSLConstList papszListIn);
544 : /** Move assignment operator */
545 : CPLStringList &operator=(CPLStringList &&oOther);
546 :
547 : /** Return string at specified index */
548 : char *operator[](int i);
549 :
550 : /** Return string at specified index */
551 1187 : char *operator[](size_t i)
552 : {
553 1187 : return (*this)[static_cast<int>(i)];
554 : }
555 :
556 : /** Return string at specified index */
557 : const char *operator[](int i) const;
558 :
559 : /** Return string at specified index */
560 84 : const char *operator[](size_t i) const
561 : {
562 84 : return (*this)[static_cast<int>(i)];
563 : }
564 :
565 : /** Return value corresponding to pszKey, or nullptr */
566 3937 : const char *operator[](const char *pszKey) const
567 : {
568 3937 : return FetchNameValue(pszKey);
569 : }
570 :
571 : /** Return first element */
572 : inline const char *front() const
573 : {
574 : return papszList[0];
575 : }
576 :
577 : /** Return last element */
578 393062 : inline const char *back() const
579 : {
580 393062 : return papszList[size() - 1];
581 : }
582 :
583 : /** begin() implementation */
584 3525 : const char *const *begin() const
585 : {
586 3525 : return papszList ? &papszList[0] : nullptr;
587 : }
588 :
589 : /** end() implementation */
590 3525 : const char *const *end() const
591 : {
592 3525 : return papszList ? &papszList[size()] : nullptr;
593 : }
594 :
595 : /** Return list. Ownership remains to the object */
596 1065363 : char **List()
597 : {
598 1065363 : return papszList;
599 : }
600 :
601 : /** Return list. Ownership remains to the object */
602 451794 : CSLConstList List() const
603 : {
604 451794 : return papszList;
605 : }
606 :
607 : char **StealList();
608 :
609 : CPLStringList &Sort();
610 :
611 : /** Returns whether the list is sorted */
612 17258800 : int IsSorted() const
613 : {
614 17258800 : return bIsSorted;
615 : }
616 :
617 : /** Return lists */
618 1179 : operator char **(void)
619 : {
620 1179 : return List();
621 : }
622 :
623 : /** Return lists */
624 534 : operator CSLConstList(void) const
625 : {
626 534 : return List();
627 : }
628 :
629 : /** Return the list as a vector of strings */
630 411 : operator std::vector<std::string>(void) const
631 : {
632 411 : return std::vector<std::string>{begin(), end()};
633 : }
634 : };
635 :
636 : #ifdef GDAL_COMPILATION
637 :
638 : #include <iterator> // For std::input_iterator_tag
639 : #include <memory>
640 : #include <utility> // For std::pair
641 :
642 : /*! @cond Doxygen_Suppress */
643 : struct CPL_DLL CSLDestroyReleaser
644 : {
645 : void operator()(char **papszStr) const
646 : {
647 : CSLDestroy(papszStr);
648 : }
649 : };
650 :
651 : /*! @endcond */
652 :
653 : /** Unique pointer type to use with CSL functions returning a char** */
654 : using CSLUniquePtr = std::unique_ptr<char *, CSLDestroyReleaser>;
655 :
656 : /** Unique pointer type to use with functions returning a char* to release
657 : * with VSIFree */
658 : using CPLCharUniquePtr = std::unique_ptr<char, VSIFreeReleaser>;
659 :
660 : namespace cpl
661 : {
662 :
663 : /*! @cond Doxygen_Suppress */
664 : /** Iterator for a CSLConstList */
665 : struct CPL_DLL CSLIterator
666 : {
667 : using iterator_category = std::input_iterator_tag;
668 : using difference_type = std::ptrdiff_t;
669 : using value_type = const char *;
670 : using pointer = value_type *;
671 : using reference = value_type &;
672 :
673 : CSLConstList m_papszList = nullptr;
674 : bool m_bAtEnd = false;
675 :
676 134366 : inline const char *operator*() const
677 : {
678 134366 : return *m_papszList;
679 : }
680 :
681 134302 : inline CSLIterator &operator++()
682 : {
683 134302 : if (m_papszList)
684 134302 : ++m_papszList;
685 134302 : return *this;
686 : }
687 :
688 : bool operator==(const CSLIterator &other) const;
689 :
690 241934 : inline bool operator!=(const CSLIterator &other) const
691 : {
692 241934 : return !(operator==(other));
693 : }
694 : };
695 :
696 : /*! @endcond */
697 :
698 : /** Wrapper for a CSLConstList that can be used with C++ iterators.
699 : *
700 : * @since GDAL 3.9
701 : */
702 : struct CPL_DLL CSLIteratorWrapper
703 : {
704 : public:
705 : /** Constructor */
706 107631 : inline explicit CSLIteratorWrapper(CSLConstList papszList)
707 107631 : : m_papszList(papszList)
708 : {
709 107631 : }
710 :
711 : /** Get the begin of the list */
712 107632 : inline CSLIterator begin() const
713 : {
714 107632 : return {m_papszList, false};
715 : }
716 :
717 : /** Get the end of the list */
718 107632 : inline CSLIterator end() const
719 : {
720 107632 : return {m_papszList, true};
721 : }
722 :
723 : private:
724 : CSLConstList m_papszList;
725 : };
726 :
727 : /** Wraps a CSLConstList in a structure that can be used with C++ iterators.
728 : *
729 : * @since GDAL 3.9
730 : */
731 107633 : inline CSLIteratorWrapper Iterate(CSLConstList papszList)
732 : {
733 107633 : return CSLIteratorWrapper{papszList};
734 : }
735 :
736 : /*! @cond Doxygen_Suppress */
737 1484 : inline CSLIteratorWrapper Iterate(const CPLStringList &aosList)
738 : {
739 1484 : return Iterate(aosList.List());
740 : }
741 :
742 : /*! @endcond */
743 :
744 : /*! @cond Doxygen_Suppress */
745 : inline CSLIteratorWrapper Iterate(char **) = delete;
746 :
747 : /*! @endcond */
748 :
749 : /*! @cond Doxygen_Suppress */
750 : /** Iterator for a CSLConstList as (name, value) pairs. */
751 : struct CPL_DLL CSLNameValueIterator
752 : {
753 : using iterator_category = std::input_iterator_tag;
754 : using difference_type = std::ptrdiff_t;
755 : using value_type = std::pair<const char *, const char *>;
756 : using pointer = value_type *;
757 : using reference = value_type &;
758 :
759 : CSLConstList m_papszList = nullptr;
760 : bool m_bReturnNullKeyIfNotNameValue = false;
761 : std::string m_osKey{};
762 :
763 : value_type operator*();
764 :
765 1090 : inline CSLNameValueIterator &operator++()
766 : {
767 1090 : if (m_papszList)
768 1090 : ++m_papszList;
769 1090 : return *this;
770 : }
771 :
772 3533 : inline bool operator==(const CSLNameValueIterator &other) const
773 : {
774 3533 : return m_papszList == other.m_papszList;
775 : }
776 :
777 3531 : inline bool operator!=(const CSLNameValueIterator &other) const
778 : {
779 3531 : return !(operator==(other));
780 : }
781 : };
782 :
783 : /*! @endcond */
784 :
785 : /** Wrapper for a CSLConstList that can be used with C++ iterators
786 : * to get (name, value) pairs.
787 : *
788 : * This can for example be used to do the following:
789 : * for (const auto& [name, value]: cpl::IterateNameValue(papszList)) {}
790 : *
791 : * Note that a (name, value) pair returned by dereferencing an iterator
792 : * is invalidated by the next iteration on the iterator.
793 : *
794 : * @since GDAL 3.9
795 : */
796 : struct CPL_DLL CSLNameValueIteratorWrapper
797 : {
798 : public:
799 : /** Constructor */
800 2443 : inline explicit CSLNameValueIteratorWrapper(
801 : CSLConstList papszList, bool bReturnNullKeyIfNotNameValue)
802 2443 : : m_papszList(papszList),
803 2443 : m_bReturnNullKeyIfNotNameValue(bReturnNullKeyIfNotNameValue)
804 : {
805 2443 : }
806 :
807 : /** Get the begin of the list */
808 2443 : inline CSLNameValueIterator begin() const
809 : {
810 2443 : return {m_papszList, m_bReturnNullKeyIfNotNameValue};
811 : }
812 :
813 : /** Get the end of the list */
814 : CSLNameValueIterator end() const;
815 :
816 : private:
817 : CSLConstList m_papszList;
818 : const bool m_bReturnNullKeyIfNotNameValue;
819 : };
820 :
821 : /** Wraps a CSLConstList in a structure that can be used with C++ iterators
822 : * to get (name, value) pairs.
823 : *
824 : * This can for example be used to do the following:
825 : * for (const auto& [name, value]: cpl::IterateNameValue(papszList)) {}
826 : *
827 : * Note that a (name, value) pair returned by dereferencing an iterator
828 : * is invalidated by the next iteration on the iterator.
829 : *
830 : * @param papszList List to iterate over.
831 : * @param bReturnNullKeyIfNotNameValue When this is set to true, if a string
832 : * contained in the list if not of the form name=value, then the value of
833 : * the iterator will be (nullptr, string).
834 : *
835 : * @since GDAL 3.9
836 : */
837 : inline CSLNameValueIteratorWrapper
838 2443 : IterateNameValue(CSLConstList papszList,
839 : bool bReturnNullKeyIfNotNameValue = false)
840 : {
841 2443 : return CSLNameValueIteratorWrapper{papszList,
842 2443 : bReturnNullKeyIfNotNameValue};
843 : }
844 :
845 : /*! @cond Doxygen_Suppress */
846 : inline CSLNameValueIteratorWrapper
847 1545 : IterateNameValue(const CPLStringList &aosList,
848 : bool bReturnNullKeyIfNotNameValue = false)
849 : {
850 1545 : return IterateNameValue(aosList.List(), bReturnNullKeyIfNotNameValue);
851 : }
852 :
853 : /*! @endcond */
854 :
855 : /*! @cond Doxygen_Suppress */
856 : inline CSLIteratorWrapper IterateNameValue(char **, bool = false) = delete;
857 :
858 : /*! @endcond */
859 :
860 : /** Converts a CSLConstList to a std::vector<std::string> */
861 94 : inline std::vector<std::string> ToVector(CSLConstList papszList)
862 : {
863 188 : return CPLStringList::BoundToConstList(papszList);
864 : }
865 :
866 : inline std::vector<std::string> ToVector(char **) = delete;
867 :
868 : } // namespace cpl
869 :
870 : #endif
871 :
872 : } // extern "C++"
873 :
874 : #endif /* def __cplusplus && !CPL_SUPRESS_CPLUSPLUS */
875 :
876 : #endif /* CPL_STRING_H_INCLUDED */
|