1 /******************************************************************************
2  * $Id: cpl_vsi.h a044c83f8091becdd11e27be6e9c08d0d3478126 2021-02-24 11:38:17 +0100 Even Rouault $
3  *
4  * Project:  CPL - Common Portability Library
5  * Author:   Frank Warmerdam, warmerdam@pobox.com
6  * Purpose:  Include file defining Virtual File System (VSI) functions, a
7  *           layer over POSIX file and other system services.
8  *
9  ******************************************************************************
10  * Copyright (c) 1998, Frank Warmerdam
11  * Copyright (c) 2008-2014, Even Rouault <even dot rouault at spatialys.com>
12  *
13  * Permission is hereby granted, free of charge, to any person obtaining a
14  * copy of this software and associated documentation files (the "Software"),
15  * to deal in the Software without restriction, including without limitation
16  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17  * and/or sell copies of the Software, and to permit persons to whom the
18  * Software is furnished to do so, subject to the following conditions:
19  *
20  * The above copyright notice and this permission notice shall be included
21  * in all copies or substantial portions of the Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29  * DEALINGS IN THE SOFTWARE.
30  ****************************************************************************/
31 
32 #ifndef CPL_VSI_H_INCLUDED
33 #define CPL_VSI_H_INCLUDED
34 
35 #include "cpl_port.h"
36 #include "cpl_progress.h"
37 
38 /**
39  * \file cpl_vsi.h
40  *
41  * Standard C Covers
42  *
43  * The VSI functions are intended to be hookable aliases for Standard C
44  * I/O, memory allocation and other system functions. They are intended
45  * to allow virtualization of disk I/O so that non file data sources
46  * can be made to appear as files, and so that additional error trapping
47  * and reporting can be interested.  The memory access API is aliased
48  * so that special application memory management services can be used.
49  *
50  * It is intended that each of these functions retains exactly the same
51  * calling pattern as the original Standard C functions they relate to.
52  * This means we don't have to provide custom documentation, and also means
53  * that the default implementation is very simple.
54  */
55 
56 /* -------------------------------------------------------------------- */
57 /*      We need access to ``struct stat''.                              */
58 /* -------------------------------------------------------------------- */
59 
60 /* Unix */
61 #if !defined(_WIN32)
62 #  include <unistd.h>
63 #endif
64 
65 /* Windows */
66 #include <sys/stat.h>
67 
68 CPL_C_START
69 
70 /*! @cond Doxygen_Suppress */
71 #ifdef ENABLE_EXPERIMENTAL_CPL_WARN_UNUSED_RESULT
72 #define EXPERIMENTAL_CPL_WARN_UNUSED_RESULT CPL_WARN_UNUSED_RESULT
73 #else
74 #define EXPERIMENTAL_CPL_WARN_UNUSED_RESULT
75 #endif
76 /*! @endcond */
77 
78 /* ==================================================================== */
79 /*      stdio file access functions.  These do not support large       */
80 /*      files, and do not go through the virtualization API.           */
81 /* ==================================================================== */
82 
83 /*! @cond Doxygen_Suppress */
84 
85 FILE CPL_DLL *  VSIFOpen( const char *, const char * ) CPL_WARN_UNUSED_RESULT;
86 int CPL_DLL     VSIFClose( FILE * );
87 int CPL_DLL     VSIFSeek( FILE *, long, int ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
88 long CPL_DLL    VSIFTell( FILE * ) CPL_WARN_UNUSED_RESULT;
89 void CPL_DLL    VSIRewind( FILE * );
90 void CPL_DLL    VSIFFlush( FILE * );
91 
92 size_t CPL_DLL  VSIFRead( void *, size_t, size_t, FILE * ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
93 size_t CPL_DLL  VSIFWrite( const void *, size_t, size_t, FILE * ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
94 char CPL_DLL   *VSIFGets( char *, int, FILE * ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
95 int CPL_DLL     VSIFPuts( const char *, FILE * ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
96 int CPL_DLL     VSIFPrintf( FILE *, CPL_FORMAT_STRING(const char *), ... ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT CPL_PRINT_FUNC_FORMAT(2, 3);
97 
98 int CPL_DLL     VSIFGetc( FILE * ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
99 int CPL_DLL     VSIFPutc( int, FILE * ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
100 int CPL_DLL     VSIUngetc( int, FILE * ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
101 int CPL_DLL     VSIFEof( FILE * ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
102 
103 /*! @endcond */
104 
105 /* ==================================================================== */
106 /*      VSIStat() related.                                              */
107 /* ==================================================================== */
108 
109 /*! @cond Doxygen_Suppress */
110 typedef struct stat VSIStatBuf;
111 int CPL_DLL VSIStat( const char *, VSIStatBuf * ) CPL_WARN_UNUSED_RESULT;
112 /*! @endcond */
113 
114 #ifdef _WIN32
115 #  define VSI_ISLNK(x)  ( 0 )            /* N/A on Windows */
116 #  define VSI_ISREG(x)  ((x) & S_IFREG)
117 #  define VSI_ISDIR(x)  ((x) & S_IFDIR)
118 #  define VSI_ISCHR(x)  ((x) & S_IFCHR)
119 #  define VSI_ISBLK(x)  ( 0 )            /* N/A on Windows */
120 #else
121 /** Test if the file is a symbolic link */
122 #  define VSI_ISLNK(x)  S_ISLNK(x)
123 /** Test if the file is a regular file */
124 #  define VSI_ISREG(x)  S_ISREG(x)
125 /** Test if the file is a directory */
126 #  define VSI_ISDIR(x)  S_ISDIR(x)
127 /*! @cond Doxygen_Suppress */
128 #  define VSI_ISCHR(x)  S_ISCHR(x)
129 #  define VSI_ISBLK(x)  S_ISBLK(x)
130 /*! @endcond */
131 #endif
132 
133 /* ==================================================================== */
134 /*      64bit stdio file access functions.  If we have a big size       */
135 /*      defined, then provide prototypes for the large file API,        */
136 /*      otherwise redefine to use the regular api.                      */
137 /* ==================================================================== */
138 
139 /** Type for a file offset */
140 typedef GUIntBig vsi_l_offset;
141 /** Maximum value for a file offset */
142 #define VSI_L_OFFSET_MAX GUINTBIG_MAX
143 
144 /*! @cond Doxygen_Suppress */
145 /* Make VSIL_STRICT_ENFORCE active in DEBUG builds */
146 #ifdef DEBUG
147 #define VSIL_STRICT_ENFORCE
148 #endif
149 /*! @endcond */
150 
151 #ifdef VSIL_STRICT_ENFORCE
152 /** Opaque type for a FILE that implements the VSIVirtualHandle API */
153 typedef struct _VSILFILE VSILFILE;
154 #else
155 /** Opaque type for a FILE that implements the VSIVirtualHandle API */
156 typedef FILE VSILFILE;
157 #endif
158 
159 VSILFILE CPL_DLL *  VSIFOpenL( const char *, const char * ) CPL_WARN_UNUSED_RESULT;
160 VSILFILE CPL_DLL *  VSIFOpenExL( const char *, const char *, int ) CPL_WARN_UNUSED_RESULT;
161 VSILFILE CPL_DLL *  VSIFOpenEx2L( const char *, const char *, int, CSLConstList ) CPL_WARN_UNUSED_RESULT;
162 int CPL_DLL     VSIFCloseL( VSILFILE * ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
163 int CPL_DLL     VSIFSeekL( VSILFILE *, vsi_l_offset, int ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
164 vsi_l_offset CPL_DLL VSIFTellL( VSILFILE * ) CPL_WARN_UNUSED_RESULT;
165 void CPL_DLL    VSIRewindL( VSILFILE * );
166 size_t CPL_DLL  VSIFReadL( void *, size_t, size_t, VSILFILE * ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
167 int CPL_DLL     VSIFReadMultiRangeL( int nRanges, void ** ppData, const vsi_l_offset* panOffsets, const size_t* panSizes, VSILFILE * ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
168 size_t CPL_DLL  VSIFWriteL( const void *, size_t, size_t, VSILFILE * ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
169 int CPL_DLL     VSIFEofL( VSILFILE * ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
170 int CPL_DLL     VSIFTruncateL( VSILFILE *, vsi_l_offset ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
171 int CPL_DLL     VSIFFlushL( VSILFILE * ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
172 int CPL_DLL     VSIFPrintfL( VSILFILE *, CPL_FORMAT_STRING(const char *), ... ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT CPL_PRINT_FUNC_FORMAT(2, 3);
173 int CPL_DLL     VSIFPutcL( int, VSILFILE * ) EXPERIMENTAL_CPL_WARN_UNUSED_RESULT;
174 
175 /** Range status */
176 typedef enum
177 {
178     VSI_RANGE_STATUS_UNKNOWN, /**< Unknown */
179     VSI_RANGE_STATUS_DATA,    /**< Data present */
180     VSI_RANGE_STATUS_HOLE     /**< Hole */
181 } VSIRangeStatus;
182 
183 VSIRangeStatus CPL_DLL VSIFGetRangeStatusL( VSILFILE * fp, vsi_l_offset nStart, vsi_l_offset nLength );
184 
185 int CPL_DLL     VSIIngestFile( VSILFILE* fp,
186                                const char* pszFilename,
187                                GByte** ppabyRet,
188                                vsi_l_offset* pnSize,
189                                GIntBig nMaxSize ) CPL_WARN_UNUSED_RESULT;
190 
191 int CPL_DLL     VSIOverwriteFile( VSILFILE* fpTarget, const char* pszSourceFilename ) CPL_WARN_UNUSED_RESULT;
192 
193 #if defined(VSI_STAT64_T)
194 /** Type for VSIStatL() */
195 typedef struct VSI_STAT64_T VSIStatBufL;
196 #else
197 /** Type for VSIStatL() */
198 #define VSIStatBufL    VSIStatBuf
199 #endif
200 
201 int CPL_DLL     VSIStatL( const char *, VSIStatBufL * ) CPL_WARN_UNUSED_RESULT;
202 
203 /** Flag provided to VSIStatExL() to test if the file exists */
204 #define VSI_STAT_EXISTS_FLAG         0x1
205 /** Flag provided to VSIStatExL() to query the nature (file/dir) of the file */
206 #define VSI_STAT_NATURE_FLAG         0x2
207 /** Flag provided to VSIStatExL() to query the file size */
208 #define VSI_STAT_SIZE_FLAG           0x4
209 /** Flag provided to VSIStatExL() to issue a VSIError in case of failure */
210 #define VSI_STAT_SET_ERROR_FLAG      0x8
211 
212 int CPL_DLL     VSIStatExL( const char * pszFilename, VSIStatBufL * psStatBuf, int nFlags ) CPL_WARN_UNUSED_RESULT;
213 
214 int CPL_DLL     VSIIsCaseSensitiveFS( const char * pszFilename );
215 
216 int CPL_DLL     VSISupportsSparseFiles( const char* pszPath );
217 
218 int CPL_DLL     VSIHasOptimizedReadMultiRange( const char* pszPath );
219 
220 const char CPL_DLL *VSIGetActualURL( const char* pszFilename );
221 
222 char CPL_DLL *VSIGetSignedURL( const char* pszFilename, CSLConstList papszOptions );
223 
224 const char CPL_DLL *VSIGetFileSystemOptions( const char* pszFilename );
225 
226 char CPL_DLL **VSIGetFileSystemsPrefixes( void );
227 
228 void CPL_DLL   *VSIFGetNativeFileDescriptorL( VSILFILE* );
229 
230 char CPL_DLL  **VSIGetFileMetadata( const char * pszFilename, const char* pszDomain,
231                                     CSLConstList papszOptions ) CPL_WARN_UNUSED_RESULT;
232 
233 int CPL_DLL VSISetFileMetadata( const char * pszFilename,
234                                 CSLConstList papszMetadata,
235                                 const char* pszDomain,
236                                 CSLConstList papszOptions );
237 
238 /* ==================================================================== */
239 /*      Memory allocation                                               */
240 /* ==================================================================== */
241 
242 void CPL_DLL   *VSICalloc( size_t, size_t ) CPL_WARN_UNUSED_RESULT;
243 void CPL_DLL   *VSIMalloc( size_t ) CPL_WARN_UNUSED_RESULT;
244 void CPL_DLL    VSIFree( void * );
245 void CPL_DLL   *VSIRealloc( void *, size_t ) CPL_WARN_UNUSED_RESULT;
246 char CPL_DLL   *VSIStrdup( const char * ) CPL_WARN_UNUSED_RESULT;
247 
248 void CPL_DLL   *VSIMallocAligned( size_t nAlignment, size_t nSize ) CPL_WARN_UNUSED_RESULT;
249 void CPL_DLL   *VSIMallocAlignedAuto( size_t nSize ) CPL_WARN_UNUSED_RESULT;
250 void CPL_DLL    VSIFreeAligned( void* ptr );
251 
252 void CPL_DLL   *VSIMallocAlignedAutoVerbose( size_t nSize, const char* pszFile, int nLine ) CPL_WARN_UNUSED_RESULT;
253 /** VSIMallocAlignedAutoVerbose() with FILE and LINE reporting */
254 #define VSI_MALLOC_ALIGNED_AUTO_VERBOSE( size ) VSIMallocAlignedAutoVerbose(size,__FILE__,__LINE__)
255 
256 /**
257  VSIMalloc2 allocates (nSize1 * nSize2) bytes.
258  In case of overflow of the multiplication, or if memory allocation fails, a
259  NULL pointer is returned and a CE_Failure error is raised with CPLError().
260  If nSize1 == 0 || nSize2 == 0, a NULL pointer will also be returned.
261  CPLFree() or VSIFree() can be used to free memory allocated by this function.
262 */
263 void CPL_DLL *VSIMalloc2( size_t nSize1, size_t nSize2 ) CPL_WARN_UNUSED_RESULT;
264 
265 /**
266  VSIMalloc3 allocates (nSize1 * nSize2 * nSize3) bytes.
267  In case of overflow of the multiplication, or if memory allocation fails, a
268  NULL pointer is returned and a CE_Failure error is raised with CPLError().
269  If nSize1 == 0 || nSize2 == 0 || nSize3 == 0, a NULL pointer will also be returned.
270  CPLFree() or VSIFree() can be used to free memory allocated by this function.
271 */
272 void CPL_DLL *VSIMalloc3( size_t nSize1, size_t nSize2, size_t nSize3 ) CPL_WARN_UNUSED_RESULT;
273 
274 /** VSIMallocVerbose */
275 void CPL_DLL   *VSIMallocVerbose( size_t nSize, const char* pszFile, int nLine ) CPL_WARN_UNUSED_RESULT;
276 /** VSI_MALLOC_VERBOSE */
277 #define VSI_MALLOC_VERBOSE( size ) VSIMallocVerbose(size,__FILE__,__LINE__)
278 
279 /** VSIMalloc2Verbose */
280 void CPL_DLL   *VSIMalloc2Verbose( size_t nSize1, size_t nSize2, const char* pszFile, int nLine ) CPL_WARN_UNUSED_RESULT;
281 /** VSI_MALLOC2_VERBOSE */
282 #define VSI_MALLOC2_VERBOSE( nSize1, nSize2 ) VSIMalloc2Verbose(nSize1,nSize2,__FILE__,__LINE__)
283 
284 /** VSIMalloc3Verbose */
285 void CPL_DLL   *VSIMalloc3Verbose( size_t nSize1, size_t nSize2, size_t nSize3, const char* pszFile, int nLine ) CPL_WARN_UNUSED_RESULT;
286 /** VSI_MALLOC3_VERBOSE */
287 #define VSI_MALLOC3_VERBOSE( nSize1, nSize2, nSize3 ) VSIMalloc3Verbose(nSize1,nSize2,nSize3,__FILE__,__LINE__)
288 
289 /** VSICallocVerbose */
290 void CPL_DLL   *VSICallocVerbose(  size_t nCount, size_t nSize, const char* pszFile, int nLine ) CPL_WARN_UNUSED_RESULT;
291 /** VSI_CALLOC_VERBOSE */
292 #define VSI_CALLOC_VERBOSE( nCount, nSize ) VSICallocVerbose(nCount,nSize,__FILE__,__LINE__)
293 
294 /** VSIReallocVerbose */
295 void CPL_DLL   *VSIReallocVerbose(  void* pOldPtr, size_t nNewSize, const char* pszFile, int nLine ) CPL_WARN_UNUSED_RESULT;
296 /** VSI_REALLOC_VERBOSE */
297 #define VSI_REALLOC_VERBOSE( pOldPtr, nNewSize ) VSIReallocVerbose(pOldPtr,nNewSize,__FILE__,__LINE__)
298 
299 /** VSIStrdupVerbose */
300 char CPL_DLL   *VSIStrdupVerbose(  const char* pszStr, const char* pszFile, int nLine ) CPL_WARN_UNUSED_RESULT;
301 /** VSI_STRDUP_VERBOSE */
302 #define VSI_STRDUP_VERBOSE( pszStr ) VSIStrdupVerbose(pszStr,__FILE__,__LINE__)
303 
304 GIntBig CPL_DLL CPLGetPhysicalRAM(void);
305 GIntBig CPL_DLL CPLGetUsablePhysicalRAM(void);
306 
307 /* ==================================================================== */
308 /*      Other...                                                        */
309 /* ==================================================================== */
310 
311 /** Alias of VSIReadDir() */
312 #define CPLReadDir VSIReadDir
313 char CPL_DLL **VSIReadDir( const char * );
314 char CPL_DLL **VSIReadDirRecursive( const char *pszPath );
315 char CPL_DLL **VSIReadDirEx( const char *pszPath, int nMaxFiles );
316 char CPL_DLL **VSISiblingFiles( const char *pszPath );
317 
318 /** Opaque type for a directory iterator */
319 typedef struct VSIDIR VSIDIR;
320 
321 VSIDIR CPL_DLL *VSIOpenDir( const char *pszPath,
322                             int nRecurseDepth,
323                             const char* const *papszOptions);
324 
325 /*! @cond Doxygen_Suppress */
326 typedef struct VSIDIREntry VSIDIREntry;
327 /*! @endcond */
328 
329 /** Directory entry. */
330 struct VSIDIREntry
331 {
332     /** Filename */
333     char*        pszName;
334     /** File mode. See VSI_ISREG() / VSI_ISDIR() */
335     int          nMode;
336     /** File size */
337     vsi_l_offset nSize;
338     /** Last modification time (seconds since 1970/01/01) */
339     GIntBig      nMTime;
340     /** Whether nMode is known: 0 = unknown, 1 = known. */
341     char         bModeKnown;
342     /** Whether nSize is known: 0 = unknown, 1 = known. */
343     char         bSizeKnown;
344     /** Whether nMTime is known: 0 = unknown, 1 = known. */
345     char         bMTimeKnown;
346     /** NULL-terminated list of extra properties. */
347     char**       papszExtra;
348 
349 #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
350 /*! @cond Doxygen_Suppress */
351     VSIDIREntry();
352     ~VSIDIREntry();
353     VSIDIREntry(const VSIDIREntry&);
354     VSIDIREntry& operator=(VSIDIREntry&) = delete;
355 /*! @endcond */
356 #endif
357 };
358 
359 const VSIDIREntry CPL_DLL *VSIGetNextDirEntry(VSIDIR* dir);
360 void CPL_DLL VSICloseDir(VSIDIR* dir);
361 
362 int CPL_DLL VSIMkdir( const char * pszPathname, long mode );
363 int CPL_DLL VSIMkdirRecursive( const char * pszPathname, long mode );
364 int CPL_DLL VSIRmdir( const char * pszDirname );
365 int CPL_DLL VSIRmdirRecursive( const char * pszDirname );
366 int CPL_DLL VSIUnlink( const char * pszFilename );
367 int CPL_DLL *VSIUnlinkBatch( CSLConstList papszFiles );
368 int CPL_DLL VSIRename( const char * oldpath, const char * newpath );
369 int CPL_DLL VSISync( const char* pszSource, const char* pszTarget,
370                       const char* const * papszOptions,
371                       GDALProgressFunc pProgressFunc,
372                       void *pProgressData,
373                       char*** ppapszOutputs );
374 
375 char CPL_DLL *VSIStrerror( int );
376 GIntBig CPL_DLL VSIGetDiskFreeSpace(const char *pszDirname);
377 
378 void CPL_DLL VSINetworkStatsReset( void );
379 char CPL_DLL *VSINetworkStatsGetAsSerializedJSON( char** papszOptions );
380 
381 /* ==================================================================== */
382 /*      Install special file access handlers.                           */
383 /* ==================================================================== */
384 void CPL_DLL VSIInstallMemFileHandler(void);
385 /*! @cond Doxygen_Suppress */
386 void CPL_DLL VSIInstallLargeFileHandler(void);
387 /*! @endcond */
388 void CPL_DLL VSIInstallSubFileHandler(void);
389 void VSIInstallCurlFileHandler(void);
390 void CPL_DLL VSICurlClearCache(void);
391 void CPL_DLL VSICurlPartialClearCache(const char* pszFilenamePrefix);
392 void VSIInstallCurlStreamingFileHandler(void);
393 void VSIInstallS3FileHandler(void);
394 void VSIInstallS3StreamingFileHandler(void);
395 void VSIInstallGSFileHandler(void);
396 void VSIInstallGSStreamingFileHandler(void);
397 void VSIInstallAzureFileHandler(void);
398 void VSIInstallAzureStreamingFileHandler(void);
399 void VSIInstallADLSFileHandler(void);
400 void VSIInstallOSSFileHandler(void);
401 void VSIInstallOSSStreamingFileHandler(void);
402 void VSIInstallSwiftFileHandler(void);
403 void VSIInstallSwiftStreamingFileHandler(void);
404 void VSIInstallGZipFileHandler(void); /* No reason to export that */
405 void VSIInstallZipFileHandler(void); /* No reason to export that */
406 void VSIInstallStdinHandler(void); /* No reason to export that */
407 void VSIInstallHdfsHandler(void); /* No reason to export that */
408 void VSIInstallWebHdfsHandler(void); /* No reason to export that */
409 void VSIInstallStdoutHandler(void); /* No reason to export that */
410 void CPL_DLL VSIInstallSparseFileHandler(void);
411 void VSIInstallTarFileHandler(void); /* No reason to export that */
412 void CPL_DLL VSIInstallCryptFileHandler(void);
413 void CPL_DLL VSISetCryptKey(const GByte* pabyKey, int nKeySize);
414 /*! @cond Doxygen_Suppress */
415 void CPL_DLL VSICleanupFileManager(void);
416 /*! @endcond */
417 
418 VSILFILE CPL_DLL *VSIFileFromMemBuffer( const char *pszFilename,
419                                     GByte *pabyData,
420                                     vsi_l_offset nDataLength,
421                                     int bTakeOwnership ) CPL_WARN_UNUSED_RESULT;
422 GByte CPL_DLL *VSIGetMemFileBuffer( const char *pszFilename,
423                                     vsi_l_offset *pnDataLength,
424                                     int bUnlinkAndSeize );
425 
426 /** Callback used by VSIStdoutSetRedirection() */
427 typedef size_t (*VSIWriteFunction)(const void* ptr, size_t size, size_t nmemb, FILE* stream);
428 void CPL_DLL VSIStdoutSetRedirection( VSIWriteFunction pFct, FILE* stream );
429 
430 /**
431  * Return information about a handle. Optional (driver dependent)
432  * @since GDAL 3.0
433  */
434 typedef int            (*VSIFilesystemPluginStatCallback)          ( void *pUserData, const char *pszFilename, VSIStatBufL *pStatBuf, int nFlags );
435 /**
436  * Remove handle by name. Optional
437  * @since GDAL 3.0
438  */
439 typedef int            (*VSIFilesystemPluginUnlinkCallback)        ( void *pUserData, const char *pszFilename );
440 /**
441  * Rename handle. Optional
442  * @since GDAL 3.0
443  */
444 typedef int            (*VSIFilesystemPluginRenameCallback)        ( void *pUserData, const char *oldpath, const char *newpath );
445 /**
446  * Create Directory. Optional
447  * @since GDAL 3.0
448  */
449 typedef int            (*VSIFilesystemPluginMkdirCallback)         ( void *pUserData, const char *pszDirname, long nMode );
450 /**
451  *  Delete Directory. Optional
452  * @since GDAL 3.0
453  */
454 typedef int            (*VSIFilesystemPluginRmdirCallback)         ( void *pUserData, const char *pszDirname );
455 /**
456  * List directory content. Optional
457  * @since GDAL 3.0
458  */
459 typedef char**         (*VSIFilesystemPluginReadDirCallback)       ( void *pUserData, const char *pszDirname, int nMaxFiles );
460 /**
461  * List related files. Must return NULL if unknown, or a list of relative filenames
462  * that can be opened along the main file. If no other file than pszFilename needs to
463  * be opened, return static_cast<char**> (CPLCalloc(1,sizeof(char*)));
464  *
465  * Optional
466  * @since GDAL 3.2
467  */
468 typedef char**         (*VSIFilesystemPluginSiblingFilesCallback)       ( void *pUserData, const char *pszDirname );
469 /**
470  * Open a handle. Mandatory. Returns an opaque pointer that will be used in subsequent file I/O calls.
471  * Should return null and/or set errno if the handle does not exist or the access mode is incorrect.
472  * @since GDAL 3.0
473  */
474 typedef void*          (*VSIFilesystemPluginOpenCallback)          ( void *pUserData, const char *pszFilename, const char *pszAccess );
475 /**
476  * Return current position in handle. Mandatory
477  * @since GDAL 3.0
478  */
479 typedef vsi_l_offset   (*VSIFilesystemPluginTellCallback)          ( void *pFile );
480 /**
481  * Seek to position in handle. Mandatory except for write only handles
482  * @since GDAL 3.0
483  */
484 typedef int            (*VSIFilesystemPluginSeekCallback)          ( void *pFile, vsi_l_offset nOffset, int nWhence );
485 /**
486  * Read data from current position, returns the number of blocks correctly read.
487  * Mandatory except for write only handles
488  * @since GDAL 3.0
489  */
490 typedef size_t         (*VSIFilesystemPluginReadCallback)          ( void *pFile, void *pBuffer, size_t nSize, size_t nCount );
491 /**
492  * Read from multiple offsets. Optional, will be replaced by multiple calls to Read() if not provided
493  * @since GDAL 3.0
494  */
495 typedef int            (*VSIFilesystemPluginReadMultiRangeCallback)( void *pFile, int nRanges, void ** ppData,
496                                                                      const vsi_l_offset* panOffsets, const size_t* panSizes );
497 /**
498  * Get empty ranges. Optional
499  * @since GDAL 3.0
500  */
501 typedef VSIRangeStatus (*VSIFilesystemPluginGetRangeStatusCallback)( void *pFile, vsi_l_offset nOffset, vsi_l_offset nLength );
502 /**
503  * Has end of file been reached. Mandatory? for read handles.
504  * @since GDAL 3.0
505  */
506 typedef int            (*VSIFilesystemPluginEofCallback)           ( void *pFile );
507 /**
508  * Write bytes at current offset. Mandatory for writable handles
509  * @since GDAL 3.0
510  */
511 typedef size_t         (*VSIFilesystemPluginWriteCallback)         ( void *pFile, const void *pBuffer, size_t nSize,size_t nCount);
512 /**
513  * Sync written bytes. Optional
514  * @since GDAL 3.0
515  */
516 typedef int            (*VSIFilesystemPluginFlushCallback)         ( void *pFile );
517 /**
518  * Truncate handle. Mandatory (driver dependent?) for write handles
519  */
520 typedef int            (*VSIFilesystemPluginTruncateCallback)      ( void *pFile, vsi_l_offset nNewSize );
521 /**
522  * Close file handle. Optional
523  * @since GDAL 3.0
524  */
525 typedef int            (*VSIFilesystemPluginCloseCallback)         ( void *pFile );
526 
527 /**
528  * struct containing callbacks to used by the handler.
529  * (rw), (r), (w) or () at the end indicate whether the given callback is mandatory
530  * for reading and or writing handlers. A (?) indicates that the callback might
531  * be mandatory for certain drivers only.
532  * @since GDAL 3.0
533  */
534 typedef struct {
535     /**
536      * Optional opaque pointer passed back to filemanager callbacks (e.g. open, stat, rmdir)
537      */
538     void                                        *pUserData;
539     VSIFilesystemPluginStatCallback             stat; /**< stat handle by name (rw)*/
540     VSIFilesystemPluginUnlinkCallback           unlink; /**< unlink handle by name ()*/
541     VSIFilesystemPluginRenameCallback           rename; /**< rename handle ()*/
542     VSIFilesystemPluginMkdirCallback            mkdir; /**< make directory ()*/
543     VSIFilesystemPluginRmdirCallback            rmdir; /**< remove directory ()*/
544     VSIFilesystemPluginReadDirCallback          read_dir; /**< list directory content (r?)*/
545     VSIFilesystemPluginOpenCallback             open; /**< open handle by name (rw) */
546     VSIFilesystemPluginTellCallback             tell; /**< get current position of handle (rw) */
547     VSIFilesystemPluginSeekCallback             seek; /**< set current position of handle (rw) */
548     VSIFilesystemPluginReadCallback             read; /**< read from current position (r) */
549     VSIFilesystemPluginReadMultiRangeCallback   read_multi_range; /**< read multiple blocks ()*/
550     VSIFilesystemPluginGetRangeStatusCallback   get_range_status; /**< get range status () */
551     VSIFilesystemPluginEofCallback              eof; /**< has end of file been reached (r?) */
552     VSIFilesystemPluginWriteCallback            write; /**< write bytes to current position (w) */
553     VSIFilesystemPluginFlushCallback            flush; /**< sync bytes (w) */
554     VSIFilesystemPluginTruncateCallback         truncate; /**< truncate handle (w?) */
555     VSIFilesystemPluginCloseCallback            close; /**< close handle  (rw) */
556     size_t                                      nBufferSize; /**< buffer small reads (makes handler read only) */
557     size_t                                      nCacheSize; /**< max mem to use per file when buffering */
558     VSIFilesystemPluginSiblingFilesCallback     sibling_files; /**< list related files*/
559 /*
560     Callbacks are defined as a struct allocated by a call to VSIAllocFilesystemPluginCallbacksStruct
561     in order to try to maintain ABI stability when eventually adding a new member.
562     Any callbacks added to this struct SHOULD be added to the END of this struct
563 */
564 } VSIFilesystemPluginCallbacksStruct;
565 
566 /**
567  * return a VSIFilesystemPluginCallbacksStruct to be populated at runtime with handler callbacks
568  * @since GDAL 3.0
569  */
570 VSIFilesystemPluginCallbacksStruct CPL_DLL *VSIAllocFilesystemPluginCallbacksStruct( void );
571 
572 /**
573  * free resources allocated by VSIAllocFilesystemPluginCallbacksStruct
574  * @since GDAL 3.0
575  */
576 void CPL_DLL VSIFreeFilesystemPluginCallbacksStruct(VSIFilesystemPluginCallbacksStruct* poCb);
577 
578 /**
579  * register a handler on the given prefix. All IO on datasets opened with the filename /prefix/xxxxxx
580  * will go through these callbacks.
581  * pszPrefix must begin and end with a '/'
582  * @since GDAL 3.0
583  */
584 int CPL_DLL VSIInstallPluginHandler( const char* pszPrefix, const VSIFilesystemPluginCallbacksStruct* poCb);
585 
586 /* ==================================================================== */
587 /*      Time querying.                                                  */
588 /* ==================================================================== */
589 
590 /*! @cond Doxygen_Suppress */
591 unsigned long CPL_DLL VSITime( unsigned long * );
592 const char CPL_DLL *VSICTime( unsigned long );
593 struct tm CPL_DLL *VSIGMTime( const time_t *pnTime,
594                               struct tm *poBrokenTime );
595 struct tm CPL_DLL *VSILocalTime( const time_t *pnTime,
596                                  struct tm *poBrokenTime );
597 /*! @endcond */
598 
599 /*! @cond Doxygen_Suppress */
600 /* -------------------------------------------------------------------- */
601 /*      the following can be turned on for detailed logging of          */
602 /*      almost all IO calls.                                            */
603 /* -------------------------------------------------------------------- */
604 #ifdef VSI_DEBUG
605 
606 #ifndef DEBUG
607 #  define DEBUG
608 #endif
609 
610 #include "cpl_error.h"
611 
612 #define VSIDebug4(f,a1,a2,a3,a4)   CPLDebug( "VSI", f, a1, a2, a3, a4 );
613 #define VSIDebug3( f, a1, a2, a3 ) CPLDebug( "VSI", f, a1, a2, a3 );
614 #define VSIDebug2( f, a1, a2 )     CPLDebug( "VSI", f, a1, a2 );
615 #define VSIDebug1( f, a1 )         CPLDebug( "VSI", f, a1 );
616 #else
617 #define VSIDebug4( f, a1, a2, a3, a4 ) {}
618 #define VSIDebug3( f, a1, a2, a3 ) {}
619 #define VSIDebug2( f, a1, a2 )     {}
620 #define VSIDebug1( f, a1 )         {}
621 #endif
622 /*! @endcond */
623 
624 CPL_C_END
625 
626 #endif /* ndef CPL_VSI_H_INCLUDED */
627