GDAL

- Main Page
- Related Pages
- Classes
- Files
- Download
- Issue Tracker

- File List
- File Members

cpl_vsil_curl_class.h
1 /******************************************************************************
2 *
3 * Project: CPL - Common Portability Library
4 * Purpose: Declarations for /vsicurl/ and related file systems
5 * Author: Even Rouault, even.rouault at spatialys.com
6 *
7 ******************************************************************************
8 * Copyright (c) 2010-2018, Even Rouault <even.rouault at spatialys.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 ****************************************************************************/
28
29 #ifndef CPL_VSIL_CURL_CLASS_H_INCLUDED
30 #define CPL_VSIL_CURL_CLASS_H_INCLUDED
31
32 #ifdef HAVE_CURL
33
34 #include "cpl_aws.h"
35 #include "cpl_port.h"
36 #include "cpl_string.h"
37 #include "cpl_vsil_curl_priv.h"
38 #include "cpl_mem_cache.h"
39
40 #include <curl/curl.h>
41
42 #include <set>
43 #include <map>
44 #include <memory>
45
47
48 // 7.18.1
49 #if LIBCURL_VERSION_NUM >= 0x071201
50 #define HAVE_CURLINFO_REDIRECT_URL
51 #endif
52
53 void VSICurlStreamingClearCache( void ); // from cpl_vsil_curl_streaming.cpp
54
55 struct curl_slist* VSICurlSetOptions(CURL* hCurlHandle, const char* pszURL,
56 const char * const* papszOptions);
57 struct curl_slist* VSICurlMergeHeaders( struct curl_slist* poDest,
58 struct curl_slist* poSrcToDestroy );
59
60 namespace cpl {
61
62 typedef enum
63 {
64 EXIST_UNKNOWN = -1,
65 EXIST_NO,
66 EXIST_YES,
67 } ExistStatus;
68
69 class FileProp
70 {
71 public:
72 unsigned int nGenerationAuthParameters = 0;
73 ExistStatus eExists = EXIST_UNKNOWN;
74 vsi_l_offset fileSize = 0;
75 time_t mTime = 0;
76 time_t nExpireTimestampLocal = 0;
77 CPLString osRedirectURL{};
78 bool bHasComputedFileSize = false;
79 bool bIsDirectory = false;
80 bool bS3LikeRedirect = false;
81 CPLString ETag{};
82 };
83
84 typedef struct
85 {
86 bool bGotFileList = false;
87 unsigned int nGenerationAuthParameters = 0;
88 CPLStringList oFileList{}; /* only file name without path */
89 } CachedDirList;
90
91 typedef struct
92 {
93 char* pBuffer = nullptr;
94 size_t nSize = 0;
95 bool bIsHTTP = false;
96 bool bIsInHeader = false;
97 bool bMultiRange = false;
98 vsi_l_offset nStartOffset = 0;
99 vsi_l_offset nEndOffset = 0;
100 int nHTTPCode = 0;
101 vsi_l_offset nContentLength = 0;
102 bool bFoundContentRange = false;
103 bool bError = false;
104 bool bDownloadHeaderOnly = false;
105 bool bDetectRangeDownloadingError = false;
106 GIntBig nTimestampDate = 0; // Corresponds to Date: header field
107
108 VSILFILE *fp = nullptr;
109 VSICurlReadCbkFunc pfnReadCbk = nullptr;
110 void *pReadCbkUserData = nullptr;
111 bool bInterrupted = false;
112
113 #if LIBCURL_VERSION_NUM < 0x073600
114 // Workaround to ignore extra HTTP response headers from
115 // proxies in older versions of curl.
116 // CURLOPT_SUPPRESS_CONNECT_HEADERS fixes this
117 bool bIsProxyConnectHeader = false;
118 #endif
119 } WriteFuncStruct;
120
121 /************************************************************************/
122 /* VSICurlFilesystemHandler */
123 /************************************************************************/
124
125 class VSICurlHandle;
126
127 class VSICurlFilesystemHandler : public VSIFilesystemHandler
128 {
129 CPL_DISALLOW_COPY_ASSIGN(VSICurlFilesystemHandler)
130
131 struct FilenameOffsetPair
132 {
133 std::string filename_;
134 vsi_l_offset offset_;
135
136 FilenameOffsetPair(const std::string& filename,
137 vsi_l_offset offset) :
138 filename_(filename), offset_(offset) {}
139
140 bool operator==(const FilenameOffsetPair& other) const
141 {
142 return filename_ == other.filename_ &&
143 offset_ == other.offset_;
144 }
145 };
146 struct FilenameOffsetPairHasher
147 {
148 std::size_t operator()(const FilenameOffsetPair& k) const
149 {
150 return std::hash<std::string>()(k.filename_) ^
151 std::hash<vsi_l_offset>()(k.offset_);
152 }
153 };
154
155 using RegionCacheType =
156 lru11::Cache<FilenameOffsetPair, std::shared_ptr<std::string>,
157 lru11::NullLock,
158 std::unordered_map<
159 FilenameOffsetPair,
160 typename std::list<lru11::KeyValuePair<FilenameOffsetPair,
161 std::shared_ptr<std::string>>>::iterator,
162 FilenameOffsetPairHasher>>;
163
164 RegionCacheType oRegionCache;
165
166 lru11::Cache<std::string, FileProp> oCacheFileProp;
167
168 int nCachedFilesInDirList = 0;
169 lru11::Cache<std::string, CachedDirList> oCacheDirList;
170
171 char** ParseHTMLFileList(const char* pszFilename,
172 int nMaxFiles,
173 char* pszData,
174 bool* pbGotFileList);
175
176 protected:
177 CPLMutex *hMutex = nullptr;
178
179 virtual VSICurlHandle* CreateFileHandle(const char* pszFilename);
180 virtual char** GetFileList(const char *pszFilename,
181 int nMaxFiles,
182 bool* pbGotFileList);
183
184 void RegisterEmptyDir( const CPLString& osDirname );
185
186 bool AnalyseS3FileList( const CPLString& osBaseURL,
187 const char* pszXML,
188 CPLStringList& osFileList,
189 int nMaxFiles,
190 bool bIgnoreGlacierStorageClass,
191 bool& bIsTruncated );
192
193 void AnalyseSwiftFileList( const CPLString& osBaseURL,
194 const CPLString& osPrefix,
195 const char* pszJson,
196 CPLStringList& osFileList,
197 int nMaxFilesThisQuery,
198 int nMaxFiles,
199 bool& bIsTruncated,
200 CPLString& osNextMarker );
201
202 static const char* GetOptionsStatic();
203
204 static bool IsAllowedFilename( const char* pszFilename );
205
206 public:
207 VSICurlFilesystemHandler();
208 ~VSICurlFilesystemHandler() override;
209
210 VSIVirtualHandle *Open( const char *pszFilename,
211 const char *pszAccess,
212 bool bSetError ) override;
213
214 int Stat( const char *pszFilename, VSIStatBufL *pStatBuf,
215 int nFlags ) override;
216 int Unlink( const char *pszFilename ) override;
217 int Rename( const char *oldpath, const char *newpath ) override;
218 int Mkdir( const char *pszDirname, long nMode ) override;
219 int Rmdir( const char *pszDirname ) override;
220 char **ReadDir( const char *pszDirname ) override
221 { return ReadDirEx(pszDirname, 0); }
222 char **ReadDirEx( const char *pszDirname, int nMaxFiles ) override;
223
224 int HasOptimizedReadMultiRange( const char* /* pszPath */ )
225 override { return true; }
226
227 const char* GetActualURL(const char* pszFilename) override;
228
229 const char* GetOptions() override;
230
231 char** GetFileMetadata( const char * pszFilename, const char* pszDomain,
232 CSLConstList papszOptions ) override;
233
234 char **ReadDirInternal( const char *pszDirname, int nMaxFiles,
235 bool* pbGotFileList );
236 void InvalidateDirContent( const char *pszDirname );
237
238 virtual CPLString GetFSPrefix() { return "/vsicurl/"; }
239 virtual bool AllowCachedDataFor(const char* pszFilename);
240
241 std::shared_ptr<std::string> GetRegion( const char* pszURL,
242 vsi_l_offset nFileOffsetStart );
243
244 void AddRegion( const char* pszURL,
245 vsi_l_offset nFileOffsetStart,
246 size_t nSize,
247 const char *pData );
248
249 bool GetCachedFileProp( const char* pszURL,
250 FileProp& oFileProp );
251 void SetCachedFileProp( const char* pszURL,
252 FileProp& oFileProp );
253 void InvalidateCachedData( const char* pszURL );
254
255 CURLM *GetCurlMultiHandleFor( const CPLString& osURL );
256
257 virtual void ClearCache();
258 virtual void PartialClearCache(const char* pszFilename);
259
260
261 bool GetCachedDirList( const char* pszURL,
262 CachedDirList& oCachedDirList );
263 void SetCachedDirList( const char* pszURL,
264 CachedDirList& oCachedDirList );
265 bool ExistsInCacheDirList( const CPLString& osDirname, bool *pbIsDir );
266
267 virtual CPLString GetURLFromFilename( const CPLString& osFilename );
268 };
269
270 /************************************************************************/
271 /* VSICurlHandle */
272 /************************************************************************/
273
274 class VSICurlHandle : public VSIVirtualHandle
275 {
276 CPL_DISALLOW_COPY_ASSIGN(VSICurlHandle)
277
278 protected:
279 VSICurlFilesystemHandler* poFS = nullptr;
280
281 bool m_bCached = true;
282
283 FileProp oFileProp{};
284
285 CPLString m_osFilename{}; // e.g "/vsicurl/http://example.com/foo"
286 char* m_pszURL = nullptr; // e.g "http://example.com/foo"
287
288 char **m_papszHTTPOptions = nullptr;
289
290 vsi_l_offset lastDownloadedOffset = VSI_L_OFFSET_MAX;
291 int nBlocksToDownload = 1;
292
293 bool bStopOnInterruptUntilUninstall = false;
294 bool bInterrupted = false;
295 VSICurlReadCbkFunc pfnReadCbk = nullptr;
296 void *pReadCbkUserData = nullptr;
297
298 int m_nMaxRetry = 0;
299 double m_dfRetryDelay = 0.0;
300
301 CPLStringList m_aosHeaders{};
302
303 void DownloadRegionPostProcess( const vsi_l_offset startOffset,
304 const int nBlocks,
305 const char* pBuffer,
306 size_t nSize );
307
308 private:
309
310 vsi_l_offset curOffset = 0;
311
312 bool bEOF = false;
313
314 virtual std::string DownloadRegion(vsi_l_offset startOffset, int nBlocks);
315
316 bool m_bUseHead = false;
317
318 int ReadMultiRangeSingleGet( int nRanges, void ** ppData,
319 const vsi_l_offset* panOffsets,
320 const size_t* panSizes );
321 CPLString GetRedirectURLIfValid(bool& bHasExpired);
322
323 protected:
324 virtual struct curl_slist* GetCurlHeaders( const CPLString& /*osVerb*/,
325 const struct curl_slist* /* psExistingHeaders */)
326 { return nullptr; }
327 virtual bool AllowAutomaticRedirection() { return true; }
328 virtual bool CanRestartOnError( const char*, const char*, bool ) { return false; }
329 virtual bool UseLimitRangeGetInsteadOfHead() { return false; }
330 virtual bool IsDirectoryFromExists( const char* /*pszVerb*/, int /*response_code*/ ) { return false; }
331 virtual void ProcessGetFileSizeResult(const char* /* pszContent */ ) {}
332 void SetURL(const char* pszURL);
333 virtual bool Authenticate() { return false; }
334
335 public:
336
337 VSICurlHandle( VSICurlFilesystemHandler* poFS,
338 const char* pszFilename,
339 const char* pszURLIn = nullptr );
340 ~VSICurlHandle() override;
341
342 int Seek( vsi_l_offset nOffset, int nWhence ) override;
343 vsi_l_offset Tell() override;
344 size_t Read( void *pBuffer, size_t nSize, size_t nMemb ) override;
345 int ReadMultiRange( int nRanges, void ** ppData,
346 const vsi_l_offset* panOffsets,
347 const size_t* panSizes ) override;
348 size_t Write( const void *pBuffer, size_t nSize, size_t nMemb ) override;
349 int Eof() override;
350 int Flush() override;
351 int Close() override;
352
353 bool IsKnownFileSize() const { return oFileProp.bHasComputedFileSize; }
354 vsi_l_offset GetFileSizeOrHeaders(bool bSetError, bool bGetHeaders);
355 virtual vsi_l_offset GetFileSize( bool bSetError ) { return GetFileSizeOrHeaders(bSetError, false); }
356 bool Exists( bool bSetError );
357 bool IsDirectory() const { return oFileProp.bIsDirectory; }
358 time_t GetMTime() const { return oFileProp.mTime; }
359 const CPLStringList& GetHeaders() { return m_aosHeaders; }
360
361 int InstallReadCbk( VSICurlReadCbkFunc pfnReadCbk,
362 void* pfnUserData,
363 int bStopOnInterruptUntilUninstall );
364 int UninstallReadCbk();
365
366 const char *GetURL() const { return m_pszURL; }
367 };
368
369 /************************************************************************/
370 /* IVSIS3LikeFSHandler */
371 /************************************************************************/
372
373 class IVSIS3LikeFSHandler: public VSICurlFilesystemHandler
374 {
375 CPL_DISALLOW_COPY_ASSIGN(IVSIS3LikeFSHandler)
376
377 bool CopyFile(VSILFILE* fpIn,
378 vsi_l_offset nSourceSize,
379 const char* pszSource,
380 const char* pszTarget,
381 GDALProgressFunc pProgressFunc,
382 void *pProgressData);
383 int MkdirInternal( const char *pszDirname, bool bDoStatCheck );
384
385 protected:
386 char** GetFileList( const char *pszFilename,
387 int nMaxFiles,
388 bool* pbGotFileList ) override;
389
390 virtual IVSIS3LikeHandleHelper* CreateHandleHelper(
391 const char* pszURI, bool bAllowNoObject) = 0;
392
393 virtual int CopyObject( const char *oldpath, const char *newpath,
394 CSLConstList papszMetadata );
395
396 IVSIS3LikeFSHandler() = default;
397
398 public:
399 int Unlink( const char *pszFilename ) override;
400 int Mkdir( const char *pszDirname, long nMode ) override;
401 int Rmdir( const char *pszDirname ) override;
402 int Stat( const char *pszFilename, VSIStatBufL *pStatBuf,
403 int nFlags ) override;
404 int Rename( const char *oldpath, const char *newpath ) override;
405
406 virtual int DeleteObject( const char *pszFilename );
407
408 virtual const char* GetDebugKey() const = 0;
409
410 virtual void UpdateMapFromHandle(IVSIS3LikeHandleHelper*) {}
411 virtual void UpdateHandleFromMap( IVSIS3LikeHandleHelper * ) {}
412
413 bool Sync( const char* pszSource, const char* pszTarget,
414 const char* const * papszOptions,
415 GDALProgressFunc pProgressFunc,
416 void *pProgressData,
417 char*** ppapszOutputs ) override;
418
419 VSIDIR* OpenDir( const char *pszPath, int nRecurseDepth,
420 const char* const *papszOptions) override;
421
422 // Multipart upload
423 CPLString InitiateMultipartUpload(
424 const std::string& osFilename,
425 IVSIS3LikeHandleHelper *poS3HandleHelper,
426 int nMaxRetry,
427 double dfRetryDelay);
428 CPLString UploadPart(const CPLString& osFilename,
429 int nPartNumber,
430 const std::string& osUploadID,
431 const void* pabyBuffer,
432 size_t nBufferSize,
433 IVSIS3LikeHandleHelper *poS3HandleHelper,
434 int nMaxRetry,
435 double dfRetryDelay);
436 bool CompleteMultipart(const CPLString& osFilename,
437 const CPLString& osUploadID,
438 const std::vector<CPLString> aosEtags,
439 IVSIS3LikeHandleHelper *poS3HandleHelper,
440 int nMaxRetry,
441 double dfRetryDelay);
442 bool AbortMultipart(const CPLString& osFilename,
443 const CPLString& osUploadID,
444 IVSIS3LikeHandleHelper *poS3HandleHelper,
445 int nMaxRetry,
446 double dfRetryDelay);
447 };
448
449 /************************************************************************/
450 /* IVSIS3LikeHandle */
451 /************************************************************************/
452
453 class IVSIS3LikeHandle: public VSICurlHandle
454 {
455 CPL_DISALLOW_COPY_ASSIGN(IVSIS3LikeHandle)
456
457 protected:
458 bool UseLimitRangeGetInsteadOfHead() override { return true; }
459 bool IsDirectoryFromExists( const char* pszVerb,
460 int response_code ) override
461 {
462 // A bit dirty, but on S3, a GET on a existing directory returns a 416
463 return response_code == 416 && EQUAL(pszVerb, "GET") &&
464 CPLString(m_pszURL).back() == '/';
465 }
466 void ProcessGetFileSizeResult( const char* pszContent ) override
467 {
468 oFileProp.bIsDirectory = strstr(pszContent, "ListBucketResult") != nullptr;
469 }
470
471 public:
472 IVSIS3LikeHandle( VSICurlFilesystemHandler* poFSIn,
473 const char* pszFilename,
474 const char* pszURLIn = nullptr ) :
475 VSICurlHandle(poFSIn, pszFilename, pszURLIn) {}
476 ~IVSIS3LikeHandle() override {}
477 };
478
479 /************************************************************************/
480 /* VSIS3WriteHandle */
481 /************************************************************************/
482
483 class VSIS3WriteHandle final : public VSIVirtualHandle
484 {
485 CPL_DISALLOW_COPY_ASSIGN(VSIS3WriteHandle)
486
487 IVSIS3LikeFSHandler *m_poFS = nullptr;
488 CPLString m_osFilename{};
489 IVSIS3LikeHandleHelper *m_poS3HandleHelper = nullptr;
490 bool m_bUseChunked = false;
491
492 vsi_l_offset m_nCurOffset = 0;
493 int m_nBufferOff = 0;
494 int m_nBufferSize = 0;
495 bool m_bClosed = false;
496 GByte *m_pabyBuffer = nullptr;
497 CPLString m_osUploadID{};
498 int m_nPartNumber = 0;
499 std::vector<CPLString> m_aosEtags{};
500 bool m_bError = false;
501
502 CURLM *m_hCurlMulti = nullptr;
503 CURL *m_hCurl = nullptr;
504 const void *m_pBuffer = nullptr;
505 CPLString m_osCurlErrBuf{};
506 size_t m_nChunkedBufferOff = 0;
507 size_t m_nChunkedBufferSize = 0;
508
509 int m_nMaxRetry = 0;
510 double m_dfRetryDelay = 0.0;
511 WriteFuncStruct m_sWriteFuncHeaderData{};
512
513 bool UploadPart();
514 bool DoSinglePartPUT();
515
516 static size_t ReadCallBackBufferChunked( char *buffer, size_t size,
517 size_t nitems, void *instream );
518 size_t WriteChunked( const void *pBuffer,
519 size_t nSize, size_t nMemb );
520 int FinishChunkedTransfer();
521
522 void InvalidateParentDirectory();
523
524 public:
525 VSIS3WriteHandle( IVSIS3LikeFSHandler* poFS,
526 const char* pszFilename,
527 IVSIS3LikeHandleHelper* poS3HandleHelper,
528 bool bUseChunked );
529 ~VSIS3WriteHandle() override;
530
531 int Seek( vsi_l_offset nOffset, int nWhence ) override;
532 vsi_l_offset Tell() override;
533 size_t Read( void *pBuffer, size_t nSize, size_t nMemb ) override;
534 size_t Write( const void *pBuffer, size_t nSize, size_t nMemb ) override;
535 int Eof() override;
536 int Close() override;
537
538 bool IsOK() { return m_bUseChunked || m_pabyBuffer != nullptr; }
539 };
540
541 /************************************************************************/
542 /* VSIAppendWriteHandle */
543 /************************************************************************/
544
545 class VSIAppendWriteHandle : public VSIVirtualHandle
546 {
547 CPL_DISALLOW_COPY_ASSIGN(VSIAppendWriteHandle)
548
549 protected:
550
551 VSICurlFilesystemHandler* m_poFS = nullptr;
552 CPLString m_osFSPrefix{};
553 CPLString m_osFilename{};
554
555 vsi_l_offset m_nCurOffset = 0;
556 int m_nBufferOff = 0;
557 int m_nBufferSize = 0;
558 int m_nBufferOffReadCallback = 0;
559 bool m_bClosed = false;
560 GByte *m_pabyBuffer = nullptr;
561 bool m_bError = false;
562
563 static size_t ReadCallBackBuffer( char *buffer, size_t size,
564 size_t nitems, void *instream );
565 virtual bool Send(bool bIsLastBlock) = 0;
566
567 public:
568 VSIAppendWriteHandle( VSICurlFilesystemHandler* poFS,
569 const char* pszFSPrefix,
570 const char* pszFilename,
571 int nChunkSize );
572 virtual ~VSIAppendWriteHandle();
573
574 int Seek( vsi_l_offset nOffset, int nWhence ) override;
575 vsi_l_offset Tell() override;
576 size_t Read( void *pBuffer, size_t nSize, size_t nMemb ) override;
577 size_t Write( const void *pBuffer, size_t nSize, size_t nMemb ) override;
578 int Eof() override;
579 int Close() override;
580
581 bool IsOK() { return m_pabyBuffer != nullptr; }
582 };
583
584 /************************************************************************/
585 /* CurlRequestHelper */
586 /************************************************************************/
587
588 struct CurlRequestHelper
589 {
590 WriteFuncStruct sWriteFuncData{};
591 WriteFuncStruct sWriteFuncHeaderData{};
592 char szCurlErrBuf[CURL_ERROR_SIZE+1] = {};
593
594 CurlRequestHelper();
595 ~CurlRequestHelper();
596 long perform(CURL* hCurlHandle,
597 struct curl_slist* headers, // ownership transferred
598 VSICurlFilesystemHandler *poFS,
599 IVSIS3LikeHandleHelper *poS3HandleHelper);
600 };
601
602 int VSICURLGetDownloadChunkSize();
603
604 void VSICURLInitWriteFuncStruct( WriteFuncStruct *psStruct,
605 VSILFILE *fp,
606 VSICurlReadCbkFunc pfnReadCbk,
607 void *pReadCbkUserData );
608 size_t VSICurlHandleWriteFunc( void *buffer, size_t count,
609 size_t nmemb, void *req );
610 void MultiPerform(CURLM* hCurlMultiHandle,
611 CURL* hEasyHandle = nullptr);
612 void VSICURLResetHeaderAndWriterFunctions(CURL* hCurlHandle);
613
614 } // namespace cpl
615
617
618 #endif // HAVE_CURL
619
620 #endif // CPL_VSIL_CURL_CLASS_H_INCLUDED
cpl
Definition: cpl_conv.h:369
cpl_port.h
Core portability definitions for CPL.
VSILFILE
FILE VSILFILE
Opaque type for a FILE that implements the VSIVirtualHandle API.
Definition: cpl_vsi.h:156
GByte
unsigned char GByte
Unsigned byte type.
Definition: cpl_port.h:215
VSIVirtualHandle
Virtual file handle.
Definition: cpl_vsi_virtual.h:56
CPLString
Convenient string class based on std::string.
Definition: cpl_string.h:332
cpl_string.h
Various convenience functions for working with strings and string lists.
VSIStatBufL
struct VSI_STAT64_T VSIStatBufL
Type for VSIStatL()
Definition: cpl_vsi.h:194
EQUAL
#define EQUAL(a, b)
Alias for strcasecmp() == 0.
Definition: cpl_port.h:572
CSLConstList
char ** CSLConstList
Type of a constant null-terminated list of nul terminated strings.
Definition: cpl_port.h:1212
CPLStringList
String list class designed around our use of C "char**" string lists.
Definition: cpl_string.h:441
vsi_l_offset
GUIntBig vsi_l_offset
Type for a file offset.
Definition: cpl_vsi.h:140
GIntBig
long long GIntBig
Large signed integer type (generally 64-bit integer type).
Definition: cpl_port.h:248
VSIDIR
struct VSIDIR VSIDIR
Opaque type for a directory iterator.
Definition: cpl_vsi.h:317
CPL_DISALLOW_COPY_ASSIGN
#define CPL_DISALLOW_COPY_ASSIGN(ClassName)
Helper to remove the copy and assignment constructors so that the compiler will not generate the defa...
Definition: cpl_port.h:1003
VSI_L_OFFSET_MAX
#define VSI_L_OFFSET_MAX
Maximum value for a file offset.
Definition: cpl_vsi.h:142