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