Coverage Report

Created: 2026-04-01 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/port/cpl_conv.h
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  CPL - Common Portability Library
4
 * Purpose:  Convenience functions declarations.
5
 *           This is intended to remain light weight.
6
 * Author:   Frank Warmerdam, warmerdam@pobox.com
7
 *
8
 ******************************************************************************
9
 * Copyright (c) 1998, Frank Warmerdam
10
 * Copyright (c) 2007-2013, Even Rouault <even dot rouault at spatialys.com>
11
 *
12
 * SPDX-License-Identifier: MIT
13
 ****************************************************************************/
14
15
#ifndef CPL_CONV_H_INCLUDED
16
#define CPL_CONV_H_INCLUDED
17
18
#include "cpl_port.h"
19
#include "cpl_vsi.h"
20
#include "cpl_error.h"
21
22
#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
23
#include <cstdint>
24
#endif
25
26
/**
27
 * \file cpl_conv.h
28
 *
29
 * Various convenience functions for CPL.
30
 *
31
 */
32
33
/* -------------------------------------------------------------------- */
34
/*      Runtime check of various configuration items.                   */
35
/* -------------------------------------------------------------------- */
36
CPL_C_START
37
38
/*! @cond Doxygen_Suppress */
39
void CPL_DLL CPLVerifyConfiguration(void);
40
/*! @endcond */
41
42
bool CPL_DLL CPLIsDebugEnabled(void);
43
44
/** Special value to indicate setting the null value to a configuration option,
45
 * even if there is an environment variable defining it.
46
 *
47
 * @since 3.13
48
 */
49
40.5k
#define CPL_NULL_VALUE "__CPL_NULL_VALUE__"
50
51
const char CPL_DLL *CPL_STDCALL CPLGetConfigOption(const char *, const char *)
52
    CPL_WARN_UNUSED_RESULT;
53
const char CPL_DLL *CPL_STDCALL CPLGetThreadLocalConfigOption(
54
    const char *, const char *) CPL_WARN_UNUSED_RESULT;
55
const char CPL_DLL *CPL_STDCALL
56
CPLGetGlobalConfigOption(const char *, const char *) CPL_WARN_UNUSED_RESULT;
57
void CPL_DLL CPL_STDCALL CPLSetConfigOption(const char *, const char *);
58
void CPL_DLL CPL_STDCALL CPLSetThreadLocalConfigOption(const char *pszKey,
59
                                                       const char *pszValue);
60
void CPL_DLL CPLDeclareKnownConfigOption(const char *pszKey,
61
                                         const char *pszDefinition);
62
char CPL_DLL **CPLGetKnownConfigOptions(void);
63
64
/** Callback for CPLSubscribeToSetConfigOption() */
65
typedef void (*CPLSetConfigOptionSubscriber)(const char *pszKey,
66
                                             const char *pszValue,
67
                                             bool bThreadLocal,
68
                                             void *pUserData);
69
int CPL_DLL CPLSubscribeToSetConfigOption(
70
    CPLSetConfigOptionSubscriber pfnCallback, void *pUserData);
71
void CPL_DLL CPLUnsubscribeToSetConfigOption(int nSubscriberId);
72
73
/*! @cond Doxygen_Suppress */
74
void CPL_DLL CPL_STDCALL CPLFreeConfig(void);
75
/*! @endcond */
76
char CPL_DLL **CPLGetConfigOptions(void);
77
void CPL_DLL CPLSetConfigOptions(const char *const *papszConfigOptions);
78
char CPL_DLL **CPLGetThreadLocalConfigOptions(void);
79
void CPL_DLL
80
CPLSetThreadLocalConfigOptions(const char *const *papszConfigOptions);
81
void CPL_DLL CPLLoadConfigOptionsFromFile(const char *pszFilename,
82
                                          int bOverrideEnvVars);
83
void CPL_DLL CPLLoadConfigOptionsFromPredefinedFiles(void);
84
85
/* -------------------------------------------------------------------- */
86
/*      Safe malloc() API.  Thin cover over VSI functions with fatal    */
87
/*      error reporting if memory allocation fails.                     */
88
/* -------------------------------------------------------------------- */
89
void CPL_DLL *CPLMalloc(size_t) CPL_WARN_UNUSED_RESULT;
90
void CPL_DLL *CPLCalloc(size_t, size_t) CPL_WARN_UNUSED_RESULT;
91
void CPL_DLL *CPLRealloc(void *, size_t) CPL_WARN_UNUSED_RESULT;
92
char CPL_DLL *
93
CPLStrdup(const char *) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
94
char CPL_DLL *CPLStrlwr(char *);
95
96
/** Alias of VSIFree() */
97
215k
#define CPLFree VSIFree
98
99
/* -------------------------------------------------------------------- */
100
/*      Read a line from a text file, and strip of CR/LF.               */
101
/* -------------------------------------------------------------------- */
102
char CPL_DLL *CPLFGets(char *, int, FILE *);
103
const char CPL_DLL *CPLReadLine(FILE *);
104
const char CPL_DLL *CPLReadLineL(VSILFILE *);
105
const char CPL_DLL *CPLReadLine2L(VSILFILE *, int, CSLConstList);
106
const char CPL_DLL *CPLReadLine3L(VSILFILE *, int, int *, CSLConstList);
107
108
/* -------------------------------------------------------------------- */
109
/*      Convert ASCII string to floating point number                  */
110
/*      (THESE FUNCTIONS ARE NOT LOCALE AWARE!).                        */
111
/* -------------------------------------------------------------------- */
112
double CPL_DLL CPLAtof(const char *);
113
double CPL_DLL CPLAtofDelim(const char *, char);
114
double CPL_DLL CPLStrtod(const char *, char **);
115
double CPL_DLL CPLStrtodM(const char *, char **);
116
double CPL_DLL CPLStrtodDelim(const char *, char **, char);
117
float CPL_DLL CPLStrtof(const char *, char **);
118
float CPL_DLL CPLStrtofDelim(const char *, char **, char);
119
120
/* -------------------------------------------------------------------- */
121
/*      Convert number to string.  This function is locale agnostic     */
122
/*      (i.e. it will support "," or "." regardless of current locale)  */
123
/* -------------------------------------------------------------------- */
124
double CPL_DLL CPLAtofM(const char *);
125
126
/* -------------------------------------------------------------------- */
127
/*      Read a numeric value from an ASCII character string.            */
128
/* -------------------------------------------------------------------- */
129
char CPL_DLL *CPLScanString(const char *, int, int, int);
130
double CPL_DLL CPLScanDouble(const char *, int);
131
long CPL_DLL CPLScanLong(const char *, int);
132
unsigned long CPL_DLL CPLScanULong(const char *, int);
133
GUIntBig CPL_DLL CPLScanUIntBig(const char *, int);
134
GIntBig CPL_DLL CPLAtoGIntBig(const char *pszString);
135
GIntBig CPL_DLL CPLAtoGIntBigEx(const char *pszString, int bWarn,
136
                                int *pbOverflow);
137
void CPL_DLL *CPLScanPointer(const char *, int);
138
139
/* -------------------------------------------------------------------- */
140
/*      Print a value to an ASCII character string.                     */
141
/* -------------------------------------------------------------------- */
142
int CPL_DLL CPLPrintString(char *, const char *, int);
143
int CPL_DLL CPLPrintStringFill(char *, const char *, int);
144
int CPL_DLL CPLPrintInt32(char *, GInt32, int);
145
int CPL_DLL CPLPrintUIntBig(char *, GUIntBig, int);
146
int CPL_DLL CPLPrintDouble(char *, const char *, double, const char *);
147
int CPL_DLL CPLPrintTime(char *, int, const char *, const struct tm *,
148
                         const char *);
149
int CPL_DLL CPLPrintPointer(char *, void *, int);
150
151
#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
152
extern "C++"
153
{
154
    std::string CPL_DLL CPLFormatReadableFileSize(uint64_t nSizeInBytes);
155
    std::string CPL_DLL CPLFormatReadableFileSize(double dfSizeInBytes);
156
}
157
#endif
158
159
/* -------------------------------------------------------------------- */
160
/*      Fetch a function from DLL / so.                                 */
161
/* -------------------------------------------------------------------- */
162
163
void CPL_DLL *CPLGetSymbol(const char *, const char *);
164
165
/* -------------------------------------------------------------------- */
166
/*      Fetch executable path.                                          */
167
/* -------------------------------------------------------------------- */
168
int CPL_DLL CPLGetExecPath(char *pszPathBuf, int nMaxLength);
169
170
/* -------------------------------------------------------------------- */
171
/*      Filename handling functions.                                    */
172
/* -------------------------------------------------------------------- */
173
174
#if defined(DOXYGEN_SKIP) || !defined(__cplusplus) ||                          \
175
    !defined(GDAL_COMPILATION) ||                                              \
176
    (defined(__cplusplus) && defined(ALLOW_DEPRECATED_CPL_PATH_FUNCTIONS))
177
const char CPL_DLL *
178
CPLGetPath(const char *) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
179
const char CPL_DLL *
180
CPLGetDirname(const char *) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
181
const char CPL_DLL *
182
CPLGetBasename(const char *) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
183
const char CPL_DLL *
184
CPLGetExtension(const char *) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
185
const char CPL_DLL *CPLFormFilename(
186
    const char *pszPath, const char *pszBasename,
187
    const char *pszExtension) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
188
const char CPL_DLL *CPLFormCIFilename(
189
    const char *pszPath, const char *pszBasename,
190
    const char *pszExtension) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
191
const char CPL_DLL *CPLResetExtension(const char *, const char *)
192
    CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
193
const char CPL_DLL *CPLProjectRelativeFilename(const char *pszProjectDir,
194
                                               const char *pszSecondaryFilename)
195
    CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
196
const char CPL_DLL *
197
CPLCleanTrailingSlash(const char *) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
198
const char CPL_DLL *CPLGenerateTempFilename(const char *pszStem)
199
    CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
200
const char CPL_DLL *CPLExpandTilde(const char *pszFilename)
201
    CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
202
const char CPL_DLL *
203
CPLLaunderForFilename(const char *pszName,
204
                      const char *pszOutputPath) CPL_WARN_UNUSED_RESULT;
205
#endif
206
207
char CPL_DLL *CPLGetCurrentDir(void);
208
const char CPL_DLL *
209
CPLGetFilename(const char *) CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
210
int CPL_DLL CPLIsFilenameRelative(const char *pszFilename);
211
const char CPL_DLL *CPLExtractRelativePath(const char *, const char *, int *)
212
    CPL_WARN_UNUSED_RESULT CPL_RETURNS_NONNULL;
213
char CPL_DLL **
214
CPLCorrespondingPaths(const char *pszOldFilename, const char *pszNewFilename,
215
                      CSLConstList papszFileList) CPL_WARN_UNUSED_RESULT;
216
int CPL_DLL CPLCheckForFile(char *pszFilename, CSLConstList papszSiblingList);
217
218
const char CPL_DLL *CPLGetHomeDir(void) CPL_WARN_UNUSED_RESULT;
219
220
#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
221
222
extern "C++"
223
{
224
    std::string CPL_DLL CPLGetPathSafe(const char *) CPL_WARN_UNUSED_RESULT;
225
    std::string CPL_DLL CPLGetDirnameSafe(const char *) CPL_WARN_UNUSED_RESULT;
226
    std::string CPL_DLL CPLGetBasenameSafe(const char *) CPL_WARN_UNUSED_RESULT;
227
    std::string CPL_DLL CPLGetExtensionSafe(const char *)
228
        CPL_WARN_UNUSED_RESULT;
229
    std::string CPL_DLL CPLFormFilenameSafe(
230
        const char *pszPath, const char *pszBasename,
231
        const char *pszExtension = nullptr) CPL_WARN_UNUSED_RESULT;
232
    std::string CPL_DLL CPLFormCIFilenameSafe(
233
        const char *pszPath, const char *pszBasename,
234
        const char *pszExtension = nullptr) CPL_WARN_UNUSED_RESULT;
235
    std::string CPL_DLL CPLResetExtensionSafe(const char *, const char *)
236
        CPL_WARN_UNUSED_RESULT;
237
    std::string CPL_DLL CPLProjectRelativeFilenameSafe(
238
        const char *pszProjectDir,
239
        const char *pszSecondaryFilename) CPL_WARN_UNUSED_RESULT;
240
    std::string CPL_DLL CPLCleanTrailingSlashSafe(const char *pszPath)
241
        CPL_WARN_UNUSED_RESULT;
242
    std::string CPL_DLL CPLGenerateTempFilenameSafe(const char *pszStem)
243
        CPL_WARN_UNUSED_RESULT;
244
    std::string CPL_DLL CPLExpandTildeSafe(const char *pszFilename)
245
        CPL_WARN_UNUSED_RESULT;
246
    std::string CPL_DLL CPLLaunderForFilenameSafe(
247
        const char *pszName, const char *pszOutputPath) CPL_WARN_UNUSED_RESULT;
248
    std::string CPL_DLL CPLLaunderForFilenameSafe(
249
        const std::string &osName, char chReplacementChar = '_',
250
        const char *pszExtraReservedCharacters = nullptr)
251
        CPL_WARN_UNUSED_RESULT;
252
253
#if defined(GDAL_COMPILATION) || __cplusplus >= 201703L
254
    std::string
255
        CPL_DLL CPLLexicallyNormalize(std::string_view svPath, char sep1,
256
                                      char sep2 = 0) CPL_WARN_UNUSED_RESULT;
257
#endif
258
}
259
260
#endif  // defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
261
262
bool CPL_DLL CPLHasPathTraversal(const char *pszFilename);
263
bool CPL_DLL CPLHasUnbalancedPathTraversal(const char *pszFilename);
264
265
/* -------------------------------------------------------------------- */
266
/*      Find File Function                                              */
267
/* -------------------------------------------------------------------- */
268
269
/** Callback for CPLPushFileFinder */
270
typedef char const *(*CPLFileFinder)(const char *, const char *);
271
272
const char CPL_DLL *CPLFindFile(const char *pszClass, const char *pszBasename);
273
const char CPL_DLL *CPLDefaultFindFile(const char *pszClass,
274
                                       const char *pszBasename);
275
void CPL_DLL CPLPushFileFinder(CPLFileFinder pfnFinder);
276
CPLFileFinder CPL_DLL CPLPopFileFinder(void);
277
void CPL_DLL CPLPushFinderLocation(const char *);
278
void CPL_DLL CPLPopFinderLocation(void);
279
void CPL_DLL CPLFinderClean(void);
280
281
/* -------------------------------------------------------------------- */
282
/*      Safe version of stat() that works properly on stuff like "C:".  */
283
/* -------------------------------------------------------------------- */
284
int CPL_DLL CPLStat(const char *, VSIStatBuf *) CPL_WARN_UNUSED_RESULT;
285
286
/* -------------------------------------------------------------------- */
287
/*      Reference counted file handle manager.  Makes sharing file      */
288
/*      handles more practical.                                         */
289
/* -------------------------------------------------------------------- */
290
291
/** Information on a shared file */
292
typedef struct
293
{
294
    FILE *fp;          /**< File pointer */
295
    int nRefCount;     /**< Reference counter */
296
    int bLarge;        /**< Whether fp must be interpreted as VSIFILE* */
297
    char *pszFilename; /**< Filename */
298
    char *pszAccess;   /**< Access mode */
299
} CPLSharedFileInfo;
300
301
FILE CPL_DLL *CPLOpenShared(const char *, const char *, int);
302
void CPL_DLL CPLCloseShared(FILE *);
303
CPLSharedFileInfo CPL_DLL *CPLGetSharedList(int *);
304
void CPL_DLL CPLDumpSharedList(FILE *);
305
/*! @cond Doxygen_Suppress */
306
void CPL_DLL CPLCleanupSharedFileMutex(void);
307
/*! @endcond */
308
309
/* -------------------------------------------------------------------- */
310
/*      DMS to Dec to DMS conversion.                                   */
311
/* -------------------------------------------------------------------- */
312
double CPL_DLL CPLDMSToDec(const char *is);
313
const char CPL_DLL *CPLDecToDMS(double dfAngle, const char *pszAxis,
314
                                int nPrecision);
315
double CPL_DLL CPLPackedDMSToDec(double);
316
double CPL_DLL CPLDecToPackedDMS(double dfDec);
317
318
CPLErr CPL_DLL CPLStringToComplex(const char *pszString, double *pdfReal,
319
                                  double *pdfImag);
320
321
/* -------------------------------------------------------------------- */
322
/*      Misc other functions.                                           */
323
/* -------------------------------------------------------------------- */
324
int CPL_DLL CPLUnlinkTree(const char *);
325
int CPL_DLL CPLCopyFile(const char *pszNewPath, const char *pszOldPath);
326
int CPL_DLL CPLCopyTree(const char *pszNewPath, const char *pszOldPath);
327
int CPL_DLL CPLMoveFile(const char *pszNewPath, const char *pszOldPath);
328
int CPL_DLL CPLSymlink(const char *pszOldPath, const char *pszNewPath,
329
                       CSLConstList papszOptions);
330
int CPL_DLL CPLGetRemainingFileDescriptorCount(void);
331
332
/* -------------------------------------------------------------------- */
333
/*      Lock related functions.                                         */
334
/* -------------------------------------------------------------------- */
335
336
/** Return code of CPLLockFileEx(). */
337
typedef enum
338
{
339
    CLFS_OK,                     /**< CPLLockFileEx() succeeded. */
340
    CLFS_CANNOT_CREATE_LOCK,     /**< Lock file creation failed. */
341
    CLFS_LOCK_BUSY,              /**< Lock already taken (and still alive). */
342
    CLFS_API_MISUSE,             /**< API misuse. */
343
    CLFS_THREAD_CREATION_FAILED, /**< Thread creation failed. */
344
} CPLLockFileStatus;
345
346
/** Handle type returned by CPLLockFileEx(). */
347
typedef struct CPLLockFileStruct *CPLLockFileHandle;
348
349
CPLLockFileStatus CPL_DLL CPLLockFileEx(const char *pszLockFileName,
350
                                        CPLLockFileHandle *phLockFileHandle,
351
                                        CSLConstList papszOptions);
352
353
void CPL_DLL CPLUnlockFileEx(CPLLockFileHandle hLockFileHandle);
354
355
/* -------------------------------------------------------------------- */
356
/*      ZIP Creation.                                                   */
357
/* -------------------------------------------------------------------- */
358
359
/*! @cond Doxygen_Suppress */
360
#define CPL_ZIP_API_OFFERED
361
/*! @endcond */
362
void CPL_DLL *CPLCreateZip(const char *pszZipFilename, char **papszOptions);
363
CPLErr CPL_DLL CPLCreateFileInZip(void *hZip, const char *pszFilename,
364
                                  char **papszOptions);
365
CPLErr CPL_DLL CPLWriteFileInZip(void *hZip, const void *pBuffer,
366
                                 int nBufferSize);
367
CPLErr CPL_DLL CPLCloseFileInZip(void *hZip);
368
CPLErr CPL_DLL CPLAddFileInZip(void *hZip, const char *pszArchiveFilename,
369
                               const char *pszInputFilename, VSILFILE *fpInput,
370
                               CSLConstList papszOptions,
371
                               GDALProgressFunc pProgressFunc,
372
                               void *pProgressData);
373
CPLErr CPL_DLL CPLCloseZip(void *hZip);
374
375
/* -------------------------------------------------------------------- */
376
/*      ZLib compression                                                */
377
/* -------------------------------------------------------------------- */
378
379
void CPL_DLL *CPLZLibDeflate(const void *ptr, size_t nBytes, int nLevel,
380
                             void *outptr, size_t nOutAvailableBytes,
381
                             size_t *pnOutBytes);
382
void CPL_DLL *CPLZLibInflate(const void *ptr, size_t nBytes, void *outptr,
383
                             size_t nOutAvailableBytes, size_t *pnOutBytes);
384
void CPL_DLL *CPLZLibInflateEx(const void *ptr, size_t nBytes, void *outptr,
385
                               size_t nOutAvailableBytes,
386
                               bool bAllowResizeOutptr, size_t *pnOutBytes);
387
388
/* -------------------------------------------------------------------- */
389
/*      XML validation.                                                 */
390
/* -------------------------------------------------------------------- */
391
int CPL_DLL CPLValidateXML(const char *pszXMLFilename,
392
                           const char *pszXSDFilename,
393
                           CSLConstList papszOptions);
394
395
/* -------------------------------------------------------------------- */
396
/*      Locale handling. Prevents parallel executions of setlocale().   */
397
/* -------------------------------------------------------------------- */
398
char *CPLsetlocale(int category, const char *locale);
399
/*! @cond Doxygen_Suppress */
400
void CPLCleanupSetlocaleMutex(void);
401
/*! @endcond */
402
403
/*!
404
    CPLIsPowerOfTwo()
405
    @param i - tested number
406
    @return TRUE if i is power of two otherwise return FALSE
407
*/
408
int CPL_DLL CPLIsPowerOfTwo(unsigned int i);
409
410
/* -------------------------------------------------------------------- */
411
/*      Terminal related                                                */
412
/* -------------------------------------------------------------------- */
413
414
bool CPL_DLL CPLIsInteractive(FILE *f);
415
416
CPL_C_END
417
418
/* -------------------------------------------------------------------- */
419
/*      C++ object for temporarily forcing a LC_NUMERIC locale to "C".  */
420
/* -------------------------------------------------------------------- */
421
422
//! @cond Doxygen_Suppress
423
#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
424
425
extern "C++"
426
{
427
    class CPL_DLL CPLLocaleC
428
    {
429
        CPL_DISALLOW_COPY_ASSIGN(CPLLocaleC)
430
      public:
431
        CPLLocaleC();
432
        ~CPLLocaleC();
433
434
      private:
435
        char *pszOldLocale;
436
    };
437
438
    // Does the same as CPLLocaleC except that, when available, it tries to
439
    // only affect the current thread. But code that would be dependent of
440
    // setlocale(LC_NUMERIC, NULL) returning "C", such as current proj.4
441
    // versions, will not work depending on the actual implementation
442
    class CPLThreadLocaleCPrivate;
443
444
    class CPL_DLL CPLThreadLocaleC
445
    {
446
        CPL_DISALLOW_COPY_ASSIGN(CPLThreadLocaleC)
447
448
      public:
449
        CPLThreadLocaleC();
450
        ~CPLThreadLocaleC();
451
452
      private:
453
        CPLThreadLocaleCPrivate *m_private;
454
    };
455
}
456
457
#endif /* def __cplusplus */
458
//! @endcond
459
460
/* -------------------------------------------------------------------- */
461
/*      C++ object for temporarily forcing a config option              */
462
/* -------------------------------------------------------------------- */
463
464
//! @cond Doxygen_Suppress
465
#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
466
467
extern "C++"
468
{
469
    class CPL_DLL CPLConfigOptionSetter
470
    {
471
        CPL_DISALLOW_COPY_ASSIGN(CPLConfigOptionSetter)
472
      public:
473
        CPLConfigOptionSetter(const char *pszKey, const char *pszValue,
474
                              bool bSetOnlyIfUndefined);
475
        ~CPLConfigOptionSetter();
476
477
      private:
478
        char *m_pszKey;
479
        char *m_pszOldValue;
480
        bool m_bRestoreOldValue;
481
    };
482
}
483
484
#endif /* def __cplusplus */
485
//! @endcond
486
487
#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
488
489
extern "C++"
490
{
491
492
#ifndef DOXYGEN_SKIP
493
#include <type_traits>  // for std::is_base_of
494
#endif
495
496
    namespace cpl
497
    {
498
    /** Use cpl::down_cast<Derived*>(pointer_to_base) as equivalent of
499
     * static_cast<Derived*>(pointer_to_base) with safe checking in debug
500
     * mode.
501
     *
502
     * Only works if no virtual inheritance is involved.
503
     *
504
     * @param f pointer to a base class
505
     * @return pointer to a derived class
506
     */
507
    template <typename To, typename From> inline To down_cast(From *f)
508
49.8k
    {
509
49.8k
        static_assert(
510
49.8k
            (std::is_base_of<From,
511
49.8k
                             typename std::remove_pointer<To>::type>::value),
512
49.8k
            "target type not derived from source type");
513
49.8k
        CPLAssert(f == nullptr || dynamic_cast<To>(f) != nullptr);
514
49.8k
        return static_cast<To>(f);
515
49.8k
    }
Unexecuted instantiation: VSIGZipFilesystemHandler* cpl::down_cast<VSIGZipFilesystemHandler*, VSIFilesystemHandler>(VSIFilesystemHandler*)
Unexecuted instantiation: VSIZipReader* cpl::down_cast<VSIZipReader*, VSIArchiveReader>(VSIArchiveReader*)
Unexecuted instantiation: VSIZipWriteHandle* cpl::down_cast<VSIZipWriteHandle*, VSIVirtualHandle>(VSIVirtualHandle*)
Unexecuted instantiation: OGRPolygon const* cpl::down_cast<OGRPolygon const*, OGRGeometry const>(OGRGeometry const*)
OGRPoint* cpl::down_cast<OGRPoint*, OGRGeometry>(OGRGeometry*)
Line
Count
Source
508
9.26k
    {
509
9.26k
        static_assert(
510
9.26k
            (std::is_base_of<From,
511
9.26k
                             typename std::remove_pointer<To>::type>::value),
512
9.26k
            "target type not derived from source type");
513
9.26k
        CPLAssert(f == nullptr || dynamic_cast<To>(f) != nullptr);
514
9.26k
        return static_cast<To>(f);
515
9.26k
    }
Unexecuted instantiation: OGRPoint const* cpl::down_cast<OGRPoint const*, OGRGeometry const>(OGRGeometry const*)
OGRCurve* cpl::down_cast<OGRCurve*, OGRGeometry>(OGRGeometry*)
Line
Count
Source
508
3.36k
    {
509
3.36k
        static_assert(
510
3.36k
            (std::is_base_of<From,
511
3.36k
                             typename std::remove_pointer<To>::type>::value),
512
3.36k
            "target type not derived from source type");
513
3.36k
        CPLAssert(f == nullptr || dynamic_cast<To>(f) != nullptr);
514
3.36k
        return static_cast<To>(f);
515
3.36k
    }
Unexecuted instantiation: OGRCurve const* cpl::down_cast<OGRCurve const*, OGRGeometry const>(OGRGeometry const*)
OGRSimpleCurve* cpl::down_cast<OGRSimpleCurve*, OGRGeometry>(OGRGeometry*)
Line
Count
Source
508
11.7k
    {
509
11.7k
        static_assert(
510
11.7k
            (std::is_base_of<From,
511
11.7k
                             typename std::remove_pointer<To>::type>::value),
512
11.7k
            "target type not derived from source type");
513
11.7k
        CPLAssert(f == nullptr || dynamic_cast<To>(f) != nullptr);
514
11.7k
        return static_cast<To>(f);
515
11.7k
    }
Unexecuted instantiation: OGRSimpleCurve const* cpl::down_cast<OGRSimpleCurve const*, OGRGeometry const>(OGRGeometry const*)
Unexecuted instantiation: OGRLineString* cpl::down_cast<OGRLineString*, OGRGeometry>(OGRGeometry*)
Unexecuted instantiation: OGRLineString const* cpl::down_cast<OGRLineString const*, OGRGeometry const>(OGRGeometry const*)
Unexecuted instantiation: OGRLinearRing* cpl::down_cast<OGRLinearRing*, OGRGeometry>(OGRGeometry*)
Unexecuted instantiation: OGRLinearRing const* cpl::down_cast<OGRLinearRing const*, OGRGeometry const>(OGRGeometry const*)
Unexecuted instantiation: OGRCircularString* cpl::down_cast<OGRCircularString*, OGRGeometry>(OGRGeometry*)
Unexecuted instantiation: OGRCircularString const* cpl::down_cast<OGRCircularString const*, OGRGeometry const>(OGRGeometry const*)
OGRCompoundCurve* cpl::down_cast<OGRCompoundCurve*, OGRGeometry>(OGRGeometry*)
Line
Count
Source
508
575
    {
509
575
        static_assert(
510
575
            (std::is_base_of<From,
511
575
                             typename std::remove_pointer<To>::type>::value),
512
575
            "target type not derived from source type");
513
575
        CPLAssert(f == nullptr || dynamic_cast<To>(f) != nullptr);
514
575
        return static_cast<To>(f);
515
575
    }
Unexecuted instantiation: OGRCompoundCurve const* cpl::down_cast<OGRCompoundCurve const*, OGRGeometry const>(OGRGeometry const*)
OGRSurface* cpl::down_cast<OGRSurface*, OGRGeometry>(OGRGeometry*)
Line
Count
Source
508
521
    {
509
521
        static_assert(
510
521
            (std::is_base_of<From,
511
521
                             typename std::remove_pointer<To>::type>::value),
512
521
            "target type not derived from source type");
513
521
        CPLAssert(f == nullptr || dynamic_cast<To>(f) != nullptr);
514
521
        return static_cast<To>(f);
515
521
    }
Unexecuted instantiation: OGRSurface const* cpl::down_cast<OGRSurface const*, OGRGeometry const>(OGRGeometry const*)
OGRPolygon* cpl::down_cast<OGRPolygon*, OGRGeometry>(OGRGeometry*)
Line
Count
Source
508
518
    {
509
518
        static_assert(
510
518
            (std::is_base_of<From,
511
518
                             typename std::remove_pointer<To>::type>::value),
512
518
            "target type not derived from source type");
513
518
        CPLAssert(f == nullptr || dynamic_cast<To>(f) != nullptr);
514
518
        return static_cast<To>(f);
515
518
    }
Unexecuted instantiation: OGRTriangle* cpl::down_cast<OGRTriangle*, OGRGeometry>(OGRGeometry*)
Unexecuted instantiation: OGRTriangle const* cpl::down_cast<OGRTriangle const*, OGRGeometry const>(OGRGeometry const*)
OGRCurvePolygon* cpl::down_cast<OGRCurvePolygon*, OGRGeometry>(OGRGeometry*)
Line
Count
Source
508
13.6k
    {
509
13.6k
        static_assert(
510
13.6k
            (std::is_base_of<From,
511
13.6k
                             typename std::remove_pointer<To>::type>::value),
512
13.6k
            "target type not derived from source type");
513
13.6k
        CPLAssert(f == nullptr || dynamic_cast<To>(f) != nullptr);
514
13.6k
        return static_cast<To>(f);
515
13.6k
    }
Unexecuted instantiation: OGRCurvePolygon const* cpl::down_cast<OGRCurvePolygon const*, OGRGeometry const>(OGRGeometry const*)
OGRGeometryCollection* cpl::down_cast<OGRGeometryCollection*, OGRGeometry>(OGRGeometry*)
Line
Count
Source
508
8.92k
    {
509
8.92k
        static_assert(
510
8.92k
            (std::is_base_of<From,
511
8.92k
                             typename std::remove_pointer<To>::type>::value),
512
8.92k
            "target type not derived from source type");
513
8.92k
        CPLAssert(f == nullptr || dynamic_cast<To>(f) != nullptr);
514
8.92k
        return static_cast<To>(f);
515
8.92k
    }
Unexecuted instantiation: OGRGeometryCollection const* cpl::down_cast<OGRGeometryCollection const*, OGRGeometry const>(OGRGeometry const*)
Unexecuted instantiation: OGRMultiPoint* cpl::down_cast<OGRMultiPoint*, OGRGeometry>(OGRGeometry*)
Unexecuted instantiation: OGRMultiPoint const* cpl::down_cast<OGRMultiPoint const*, OGRGeometry const>(OGRGeometry const*)
Unexecuted instantiation: OGRMultiLineString* cpl::down_cast<OGRMultiLineString*, OGRGeometry>(OGRGeometry*)
Unexecuted instantiation: OGRMultiLineString const* cpl::down_cast<OGRMultiLineString const*, OGRGeometry const>(OGRGeometry const*)
Unexecuted instantiation: OGRMultiPolygon* cpl::down_cast<OGRMultiPolygon*, OGRGeometry>(OGRGeometry*)
Unexecuted instantiation: OGRMultiPolygon const* cpl::down_cast<OGRMultiPolygon const*, OGRGeometry const>(OGRGeometry const*)
OGRMultiCurve* cpl::down_cast<OGRMultiCurve*, OGRGeometry>(OGRGeometry*)
Line
Count
Source
508
453
    {
509
453
        static_assert(
510
453
            (std::is_base_of<From,
511
453
                             typename std::remove_pointer<To>::type>::value),
512
453
            "target type not derived from source type");
513
453
        CPLAssert(f == nullptr || dynamic_cast<To>(f) != nullptr);
514
453
        return static_cast<To>(f);
515
453
    }
Unexecuted instantiation: OGRMultiCurve const* cpl::down_cast<OGRMultiCurve const*, OGRGeometry const>(OGRGeometry const*)
Unexecuted instantiation: OGRMultiSurface* cpl::down_cast<OGRMultiSurface*, OGRGeometry>(OGRGeometry*)
Unexecuted instantiation: OGRMultiSurface const* cpl::down_cast<OGRMultiSurface const*, OGRGeometry const>(OGRGeometry const*)
Unexecuted instantiation: OGRPolyhedralSurface* cpl::down_cast<OGRPolyhedralSurface*, OGRGeometry>(OGRGeometry*)
Unexecuted instantiation: OGRPolyhedralSurface const* cpl::down_cast<OGRPolyhedralSurface const*, OGRGeometry const>(OGRGeometry const*)
Unexecuted instantiation: OGRTriangulatedSurface* cpl::down_cast<OGRTriangulatedSurface*, OGRGeometry>(OGRGeometry*)
Unexecuted instantiation: OGRTriangulatedSurface const* cpl::down_cast<OGRTriangulatedSurface const*, OGRGeometry const>(OGRGeometry const*)
OGRSimpleCurve* cpl::down_cast<OGRSimpleCurve*, OGRCurve>(OGRCurve*)
Line
Count
Source
508
793
    {
509
793
        static_assert(
510
793
            (std::is_base_of<From,
511
793
                             typename std::remove_pointer<To>::type>::value),
512
793
            "target type not derived from source type");
513
793
        CPLAssert(f == nullptr || dynamic_cast<To>(f) != nullptr);
514
793
        return static_cast<To>(f);
515
793
    }
Unexecuted instantiation: OGRSimpleCurve const* cpl::down_cast<OGRSimpleCurve const*, OGRCurve const>(OGRCurve const*)
Unexecuted instantiation: OGRLinearRing* cpl::down_cast<OGRLinearRing*, OGRCurve>(OGRCurve*)
Unexecuted instantiation: OGRCodedFieldDomain* cpl::down_cast<OGRCodedFieldDomain*, OGRFieldDomain>(OGRFieldDomain*)
Unexecuted instantiation: GDALProxyPoolDataset* cpl::down_cast<GDALProxyPoolDataset*, GDALDataset>(GDALDataset*)
Unexecuted instantiation: GDALOverviewBand* cpl::down_cast<GDALOverviewBand*, GDALRasterBand>(GDALRasterBand*)
Unexecuted instantiation: GDALOverviewDataset* cpl::down_cast<GDALOverviewDataset*, GDALDataset>(GDALDataset*)
Unexecuted instantiation: VRTSourcedRasterBand* cpl::down_cast<VRTSourcedRasterBand*, GDALRasterBand>(GDALRasterBand*)
Unexecuted instantiation: GDALDatasetFromArray* cpl::down_cast<GDALDatasetFromArray*, GDALDataset>(GDALDataset*)
Unexecuted instantiation: GDALMDArrayResampledDataset* cpl::down_cast<GDALMDArrayResampledDataset*, GDALDataset>(GDALDataset*)
Unexecuted instantiation: GTiffDataset* cpl::down_cast<GTiffDataset*, GDALDataset>(GDALDataset*)
Unexecuted instantiation: GTiffRasterBand* cpl::down_cast<GTiffRasterBand*, GDALRasterBand>(GDALRasterBand*)
Unexecuted instantiation: GTiffJPEGOverviewDS* cpl::down_cast<GTiffJPEGOverviewDS*, GDALDataset>(GDALDataset*)
Unexecuted instantiation: GTiffOddBitsBand* cpl::down_cast<GTiffOddBitsBand*, GDALRasterBand>(GDALRasterBand*)
Unexecuted instantiation: MEMRasterBand* cpl::down_cast<MEMRasterBand*, GDALRasterBand>(GDALRasterBand*)
Unexecuted instantiation: VRTDataset* cpl::down_cast<VRTDataset*, GDALDataset>(GDALDataset*)
Unexecuted instantiation: VRTSimpleSource* cpl::down_cast<VRTSimpleSource*, VRTSource>(VRTSource*)
Unexecuted instantiation: VRTComplexSource* cpl::down_cast<VRTComplexSource*, VRTSimpleSource>(VRTSimpleSource*)
Unexecuted instantiation: GDALProxyPoolRasterBand* cpl::down_cast<GDALProxyPoolRasterBand*, GDALRasterBand>(GDALRasterBand*)
Unexecuted instantiation: VRTRasterBand* cpl::down_cast<VRTRasterBand*, GDALRasterBand>(GDALRasterBand*)
Unexecuted instantiation: VRTSourcedRasterBand* cpl::down_cast<VRTSourcedRasterBand*, VRTRasterBand>(VRTRasterBand*)
Unexecuted instantiation: VRTProcessedDataset* cpl::down_cast<VRTProcessedDataset*, GDALDataset>(GDALDataset*)
Unexecuted instantiation: OGRShapeLayer* cpl::down_cast<OGRShapeLayer*, OGRLayer>(OGRLayer*)
Unexecuted instantiation: OGRShapeGeomFieldDefn* cpl::down_cast<OGRShapeGeomFieldDefn*, OGRGeomFieldDefn>(OGRGeomFieldDefn*)
Unexecuted instantiation: OGRShapeGeomFieldDefn const* cpl::down_cast<OGRShapeGeomFieldDefn const*, OGRGeomFieldDefn>(OGRGeomFieldDefn*)
Unexecuted instantiation: OGRGenSQLGeomFieldDefn const* cpl::down_cast<OGRGenSQLGeomFieldDefn const*, OGRGeomFieldDefn const>(OGRGeomFieldDefn const*)
Unexecuted instantiation: OGRUnionLayerGeomFieldDefn* cpl::down_cast<OGRUnionLayerGeomFieldDefn*, OGRGeomFieldDefn>(OGRGeomFieldDefn*)
Unexecuted instantiation: GDALInConstructionAlgorithmArg* cpl::down_cast<GDALInConstructionAlgorithmArg*, GDALAlgorithmArg>(GDALAlgorithmArg*)
Unexecuted instantiation: GDALComputedRasterBand* cpl::down_cast<GDALComputedRasterBand*, GDALRasterBand>(GDALRasterBand*)
Unexecuted instantiation: GDALComputedDataset* cpl::down_cast<GDALComputedDataset*, GDALDataset>(GDALDataset*)
Unexecuted instantiation: GDALPamRasterBand* cpl::down_cast<GDALPamRasterBand*, GDALRasterBand>(GDALRasterBand*)
Unexecuted instantiation: RawRasterBand* cpl::down_cast<RawRasterBand*, GDALRasterBand>(GDALRasterBand*)
Unexecuted instantiation: OGRCodedFieldDomain const* cpl::down_cast<OGRCodedFieldDomain const*, OGRFieldDomain const>(OGRFieldDomain const*)
Unexecuted instantiation: VRTDerivedRasterBand* cpl::down_cast<VRTDerivedRasterBand*, GDALRasterBand>(GDALRasterBand*)
Unexecuted instantiation: gdalalg_raster_tile.cpp:(anonymous namespace)::MosaicDataset* cpl::down_cast<(anonymous namespace)::MosaicDataset*, GDALDataset>(GDALDataset*)
Unexecuted instantiation: GDALApplyVSGRasterBand* cpl::down_cast<GDALApplyVSGRasterBand*, GDALRasterBand>(GDALRasterBand*)
Unexecuted instantiation: GDALApplyVSGDataset* cpl::down_cast<GDALApplyVSGDataset*, GDALDataset>(GDALDataset*)
Unexecuted instantiation: OGRRangeFieldDomain const* cpl::down_cast<OGRRangeFieldDomain const*, OGRFieldDomain const>(OGRFieldDomain const*)
Unexecuted instantiation: OGRGlobFieldDomain const* cpl::down_cast<OGRGlobFieldDomain const*, OGRFieldDomain const>(OGRFieldDomain const*)
Unexecuted instantiation: GDALColorReliefDataset* cpl::down_cast<GDALColorReliefDataset*, GDALDataset>(GDALDataset*)
Unexecuted instantiation: GDALGeneric3x3Dataset<int>* cpl::down_cast<GDALGeneric3x3Dataset<int>*, GDALDataset>(GDALDataset*)
Unexecuted instantiation: GDALGeneric3x3Dataset<float>* cpl::down_cast<GDALGeneric3x3Dataset<float>*, GDALDataset>(GDALDataset*)
Unexecuted instantiation: GDALPipelineStepAlgorithm* cpl::down_cast<GDALPipelineStepAlgorithm*, GDALAlgorithm>(GDALAlgorithm*)
516
517
    /** Computes ceil(a/b) where a and b are integers */
518
    template <class T, class U> inline T div_round_up(T a, U b)
519
1.34k
    {
520
1.34k
        return a / b + (((a % b) == 0) ? 0 : 1);
521
1.34k
    }
unsigned long cpl::div_round_up<unsigned long, unsigned long>(unsigned long, unsigned long)
Line
Count
Source
519
1.34k
    {
520
1.34k
        return a / b + (((a % b) == 0) ? 0 : 1);
521
1.34k
    }
Unexecuted instantiation: int cpl::div_round_up<int, int>(int, int)
Unexecuted instantiation: unsigned long long cpl::div_round_up<unsigned long long, unsigned long>(unsigned long long, unsigned long)
Unexecuted instantiation: unsigned long long cpl::div_round_up<unsigned long long, long long>(unsigned long long, long long)
Unexecuted instantiation: unsigned long long cpl::div_round_up<unsigned long long, unsigned long long>(unsigned long long, unsigned long long)
522
523
    }  // namespace cpl
524
}  // extern "C++"
525
526
#endif /* def __cplusplus */
527
528
#endif /* ndef CPL_CONV_H_INCLUDED */