GDAL
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 struct CachedDirList
85 {
86  bool bGotFileList = false;
87  unsigned int nGenerationAuthParameters = 0;
88  CPLStringList oFileList{}; /* only file name without path */
89 };
90 
91 struct WriteFuncStruct
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 };
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
GByte
unsigned char GByte
Unsigned byte type.
Definition: cpl_port.h:215
CPLStringList
String list class designed around our use of C "char**" string lists.
Definition: cpl_string.h:442
CPLString
Convenient string class based on std::string.
Definition: cpl_string.h:333
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
cpl_string.h
vsi_l_offset
GUIntBig vsi_l_offset
Type for a file offset.
Definition: cpl_vsi.h:140
VSIStatBufL
struct VSI_STAT64_T VSIStatBufL
Type for VSIStatL()
Definition: cpl_vsi.h:194
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_port.h
VSIVirtualHandle
Virtual file handle.
Definition: cpl_vsi_virtual.h:56
VSI_L_OFFSET_MAX
#define VSI_L_OFFSET_MAX
Maximum value for a file offset.
Definition: cpl_vsi.h:142
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
VSILFILE
FILE VSILFILE
Opaque type for a FILE that implements the VSIVirtualHandle API.
Definition: cpl_vsi.h:156