LCOV - code coverage report
Current view: top level - port - cpl_vsi_virtual.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 105 150 70.0 %
Date: 2026-03-25 11:28:37 Functions: 56 81 69.1 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  VSI Virtual File System
       4             :  * Purpose:  Declarations for classes related to the virtual filesystem.
       5             :  *           These would only be normally required by applications implementing
       6             :  *           their own virtual file system classes which should be rare.
       7             :  *           The class interface may be fragile through versions.
       8             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       9             :  *
      10             :  ******************************************************************************
      11             :  * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com>
      12             :  * Copyright (c) 2010-2014, Even Rouault <even dot rouault at spatialys.com>
      13             :  *
      14             :  * SPDX-License-Identifier: MIT
      15             :  ****************************************************************************/
      16             : 
      17             : #ifndef CPL_VSI_VIRTUAL_H_INCLUDED
      18             : #define CPL_VSI_VIRTUAL_H_INCLUDED
      19             : 
      20             : #include "cpl_progress.h"
      21             : #include "cpl_vsi.h"
      22             : #include "cpl_vsi_error.h"
      23             : #include "cpl_string.h"
      24             : 
      25             : #include <cstdint>
      26             : #include <map>
      27             : #include <memory>
      28             : #include <mutex>
      29             : #include <vector>
      30             : #include <string>
      31             : 
      32             : // To avoid aliasing to GetDiskFreeSpace to GetDiskFreeSpaceA on Windows
      33             : #ifdef GetDiskFreeSpace
      34             : #undef GetDiskFreeSpace
      35             : #endif
      36             : 
      37             : // To avoid aliasing to CopyFile to CopyFileA on Windows
      38             : #ifdef CopyFile
      39             : #undef CopyFile
      40             : #endif
      41             : 
      42             : /************************************************************************/
      43             : /*                           VSIVirtualHandle                           */
      44             : /************************************************************************/
      45             : 
      46             : /** Virtual file handle */
      47             : struct CPL_DLL VSIVirtualHandle
      48             : {
      49             :   public:
      50             :     virtual int Seek(vsi_l_offset nOffset, int nWhence) = 0;
      51             : 
      52             : #ifdef GDAL_COMPILATION
      53             :     /*! @cond Doxygen_Suppress */
      54       48356 :     inline int Seek(int &&nOffset, int nWhence)
      55             :     {
      56       48356 :         return Seek(static_cast<vsi_l_offset>(nOffset), nWhence);
      57             :     }
      58             : 
      59             :     inline int Seek(unsigned &&nOffset, int nWhence)
      60             :     {
      61             :         return Seek(static_cast<vsi_l_offset>(nOffset), nWhence);
      62             :     }
      63             : 
      64             :     template <typename T>
      65             :     inline std::enable_if_t<std::is_same_v<T, uint64_t> &&
      66             :                                 !std::is_same_v<uint64_t, vsi_l_offset>,
      67             :                             int>
      68       82873 :     Seek(T nOffset, int nWhence)
      69             :     {
      70       82873 :         return Seek(static_cast<vsi_l_offset>(nOffset), nWhence);
      71             :     }
      72             : 
      73             :     template <typename T>
      74             :     inline std::enable_if_t<std::is_same_v<T, size_t> &&
      75             :                                 !std::is_same_v<T, uint64_t> &&
      76             :                                 !std::is_same_v<size_t, unsigned> &&
      77             :                                 !std::is_same_v<size_t, vsi_l_offset>,
      78             :                             int>
      79             :     Seek(T nOffset, int nWhence) = delete;
      80             : 
      81             :     int Seek(int &nOffset, int nWhence) = delete;
      82             :     int Seek(const int &nOffset, int nWhence) = delete;
      83             :     int Seek(unsigned &nOffset, int nWhence) = delete;
      84             :     int Seek(const unsigned &nOffset, int nWhence) = delete;
      85             : /*! @endcond */
      86             : #endif
      87             : 
      88             :     virtual vsi_l_offset Tell() = 0;
      89             :     size_t Read(void *pBuffer, size_t nSize, size_t nCount);
      90             : 
      91             :     virtual size_t Read(void *pBuffer, size_t nBytes) = 0;
      92             : 
      93             :     /** Read a primitive type from LSB-ordered byte sequence.
      94             :      *
      95             :      * Failure to read the value can be detected by testing *pbError,
      96             :      * or Eof() || Error()
      97             :      *
      98             :      * @param[out] pbError Pointer to a boolean that will be set to true if
      99             :      * the value cannot be read, or nullptr.
     100             :      * Note that this boolean must be initialized to false by the caller,
     101             :      * and that this method will not set it to false.
     102             :      */
     103         379 :     template <class T> inline T ReadLSB(bool *pbError = nullptr)
     104             :     {
     105             :         T val;
     106         379 :         if (Read(&val, sizeof(val)) != sizeof(val))
     107             :         {
     108           2 :             if (pbError)
     109           2 :                 *pbError = true;
     110           2 :             return 0;
     111             :         }
     112         377 :         return CPL_AS_LSB(val);
     113             :     }
     114             : 
     115             :     /** Read a primitive type from LSB-ordered byte sequence */
     116        2111 :     template <class T> inline bool ReadLSB(T &val)
     117             :     {
     118        2111 :         if (Read(&val, sizeof(val)) != sizeof(val))
     119             :         {
     120          12 :             return false;
     121             :         }
     122        2099 :         val = CPL_AS_LSB(val);
     123        2099 :         return true;
     124             :     }
     125             : 
     126             :     bool ReadLSB(bool &) = delete;
     127             : 
     128             :     virtual int ReadMultiRange(int nRanges, void **ppData,
     129             :                                const vsi_l_offset *panOffsets,
     130             :                                const size_t *panSizes);
     131             : 
     132             :     /** This method is called when code plans to access soon one or several
     133             :      * ranges in a file. Some file systems may be able to use this hint to
     134             :      * for example asynchronously start such requests.
     135             :      *
     136             :      * Offsets may be given in a non-increasing order, and may potentially
     137             :      * overlap.
     138             :      *
     139             :      * @param nRanges Size of the panOffsets and panSizes arrays.
     140             :      * @param panOffsets Array containing the start offset of each range.
     141             :      * @param panSizes Array containing the size (in bytes) of each range.
     142             :      * @since GDAL 3.7
     143             :      */
     144          98 :     virtual void AdviseRead(CPL_UNUSED int nRanges,
     145             :                             CPL_UNUSED const vsi_l_offset *panOffsets,
     146             :                             CPL_UNUSED const size_t *panSizes)
     147             :     {
     148          98 :     }
     149             : 
     150             :     /** Return the total maximum number of bytes that AdviseRead() can handle
     151             :      * at once.
     152             :      *
     153             :      * Some AdviseRead() implementations may give up if the sum of the values
     154             :      * in the panSizes[] array provided to AdviseRead() exceeds a limit.
     155             :      *
     156             :      * Callers might use that threshold to optimize the efficiency of
     157             :      * AdviseRead().
     158             :      *
     159             :      * A returned value of 0 indicates a unknown limit.
     160             :      * @since GDAL 3.9
     161             :      */
     162         226 :     virtual size_t GetAdviseReadTotalBytesLimit() const
     163             :     {
     164         226 :         return 0;
     165             :     }
     166             : 
     167             :     virtual size_t Write(const void *pBuffer, size_t nBytes) = 0;
     168             :     size_t Write(const void *pBuffer, size_t nSize, size_t nCount);
     169             : 
     170             :     /** Write a primitive type as LSB-ordered byte sequence */
     171       18675 :     template <class T> inline bool WriteLSB(T val)
     172             :     {
     173       18675 :         val = CPL_AS_LSB(val);
     174       18675 :         return Write(&val, sizeof(val)) == sizeof(val);
     175             :     }
     176             : 
     177             :     int Printf(CPL_FORMAT_STRING(const char *pszFormat), ...)
     178             :         CPL_PRINT_FUNC_FORMAT(2, 3);
     179             : 
     180             :     virtual void ClearErr() = 0;
     181             : 
     182             :     virtual int Eof() = 0;
     183             : 
     184             :     virtual int Error() = 0;
     185             : 
     186       48853 :     virtual int Flush()
     187             :     {
     188       48853 :         return 0;
     189             :     }
     190             : 
     191             :     virtual int Close() = 0;
     192             :     // Base implementation that only supports file extension.
     193             :     virtual int Truncate(vsi_l_offset nNewSize);
     194             : 
     195           9 :     virtual void *GetNativeFileDescriptor()
     196             :     {
     197           9 :         return nullptr;
     198             :     }
     199             : 
     200         154 :     virtual VSIRangeStatus GetRangeStatus(CPL_UNUSED vsi_l_offset nOffset,
     201             :                                           CPL_UNUSED vsi_l_offset nLength)
     202             :     {
     203         154 :         return VSI_RANGE_STATUS_UNKNOWN;
     204             :     }
     205             : 
     206             :     virtual bool HasPRead() const;
     207             :     virtual size_t PRead(void *pBuffer, size_t nSize,
     208             :                          vsi_l_offset nOffset) const;
     209             : 
     210             :     /** Ask current operations to be interrupted.
     211             :      * Implementations must be thread-safe, as this will typically be called
     212             :      * from another thread than the active one for this file.
     213             :      */
     214          13 :     virtual void Interrupt()
     215             :     {
     216          13 :     }
     217             : 
     218             :     /** For a file created with CreateOnlyVisibleAtCloseTime(), ask for the
     219             :      * file to not be created at all (if possible)
     220             :      */
     221          88 :     virtual void CancelCreation()
     222             :     {
     223          88 :     }
     224             : 
     225             :     // NOTE: when adding new methods, besides the "actual" implementations,
     226             :     // also consider the VSICachedFile and VSIVirtualHandleOnlyVisibleAtCloseTime one.
     227             : 
     228      375228 :     virtual ~VSIVirtualHandle()
     229      375228 :     {
     230      375228 :     }
     231             : };
     232             : 
     233             : /************************************************************************/
     234             : /*                        VSIVirtualHandleCloser                        */
     235             : /************************************************************************/
     236             : 
     237             : /** Helper close to use with a std:unique_ptr<VSIVirtualHandle>,
     238             :  *  such as VSIVirtualHandleUniquePtr. */
     239             : struct VSIVirtualHandleCloser
     240             : 
     241             : {
     242             :     /** Operator () that closes and deletes the file handle. */
     243       55577 :     void operator()(VSIVirtualHandle *poHandle)
     244             :     {
     245       55577 :         if (poHandle)
     246             :         {
     247       55529 :             poHandle->Close();
     248       55703 :             delete poHandle;
     249             :         }
     250       55971 :     }
     251             : };
     252             : 
     253             : /** Unique pointer of VSIVirtualHandle that calls the Close() method */
     254             : typedef std::unique_ptr<VSIVirtualHandle, VSIVirtualHandleCloser>
     255             :     VSIVirtualHandleUniquePtr;
     256             : 
     257             : /************************************************************************/
     258             : /*                          VSIProxyFileHandle                          */
     259             : /************************************************************************/
     260             : 
     261             : #ifndef DOXYGEN_SKIP
     262             : class VSIProxyFileHandle /* non final */ : public VSIVirtualHandle
     263             : {
     264             :   protected:
     265             :     VSIVirtualHandleUniquePtr m_nativeHandle{};
     266             : 
     267             :   public:
     268         270 :     explicit VSIProxyFileHandle(VSIVirtualHandleUniquePtr &&nativeHandle)
     269         270 :         : m_nativeHandle(std::move(nativeHandle))
     270             :     {
     271         270 :     }
     272             : 
     273         976 :     int Seek(vsi_l_offset nOffset, int nWhence) override
     274             :     {
     275         976 :         return m_nativeHandle->Seek(nOffset, nWhence);
     276             :     }
     277             : 
     278         890 :     vsi_l_offset Tell() override
     279             :     {
     280         890 :         return m_nativeHandle->Tell();
     281             :     }
     282             : 
     283        1187 :     size_t Read(void *pBuffer, size_t nBytes) override
     284             :     {
     285        1187 :         return m_nativeHandle->Read(pBuffer, nBytes);
     286             :     }
     287             : 
     288           0 :     int ReadMultiRange(int nRanges, void **ppData,
     289             :                        const vsi_l_offset *panOffsets,
     290             :                        const size_t *panSizes) override
     291             :     {
     292           0 :         return m_nativeHandle->ReadMultiRange(nRanges, ppData, panOffsets,
     293           0 :                                               panSizes);
     294             :     }
     295             : 
     296           0 :     void AdviseRead(int nRanges, const vsi_l_offset *panOffsets,
     297             :                     const size_t *panSizes) override
     298             :     {
     299           0 :         return m_nativeHandle->AdviseRead(nRanges, panOffsets, panSizes);
     300             :     }
     301             : 
     302           0 :     size_t GetAdviseReadTotalBytesLimit() const override
     303             :     {
     304           0 :         return m_nativeHandle->GetAdviseReadTotalBytesLimit();
     305             :     }
     306             : 
     307        5800 :     size_t Write(const void *pBuffer, size_t nBytes) override
     308             :     {
     309        5800 :         return m_nativeHandle->Write(pBuffer, nBytes);
     310             :     }
     311             : 
     312           0 :     void ClearErr() override
     313             :     {
     314           0 :         return m_nativeHandle->ClearErr();
     315             :     }
     316             : 
     317           0 :     int Eof() override
     318             :     {
     319           0 :         return m_nativeHandle->Eof();
     320             :     }
     321             : 
     322           0 :     int Error() override
     323             :     {
     324           0 :         return m_nativeHandle->Error();
     325             :     }
     326             : 
     327          11 :     int Flush() override
     328             :     {
     329          11 :         return m_nativeHandle->Flush();
     330             :     }
     331             : 
     332         270 :     int Close() override
     333             :     {
     334         270 :         return m_nativeHandle->Close();
     335             :     }
     336             : 
     337           0 :     int Truncate(vsi_l_offset nNewSize) override
     338             :     {
     339           0 :         return m_nativeHandle->Truncate(nNewSize);
     340             :     }
     341             : 
     342           0 :     void *GetNativeFileDescriptor() override
     343             :     {
     344           0 :         return m_nativeHandle->GetNativeFileDescriptor();
     345             :     }
     346             : 
     347           0 :     VSIRangeStatus GetRangeStatus(vsi_l_offset nOffset,
     348             :                                   vsi_l_offset nLength) override
     349             :     {
     350           0 :         return m_nativeHandle->GetRangeStatus(nOffset, nLength);
     351             :     }
     352             : 
     353           0 :     bool HasPRead() const override
     354             :     {
     355           0 :         return m_nativeHandle->HasPRead();
     356             :     }
     357             : 
     358           0 :     size_t PRead(void *pBuffer, size_t nSize,
     359             :                  vsi_l_offset nOffset) const override
     360             :     {
     361           0 :         return m_nativeHandle->PRead(pBuffer, nSize, nOffset);
     362             :     }
     363             : 
     364           0 :     void Interrupt() override
     365             :     {
     366           0 :         m_nativeHandle->Interrupt();
     367           0 :     }
     368             : 
     369             :     void CancelCreation() override;
     370             : };
     371             : #endif
     372             : 
     373             : /************************************************************************/
     374             : /*                         VSIFilesystemHandler                         */
     375             : /************************************************************************/
     376             : 
     377             : #ifndef DOXYGEN_SKIP
     378             : class CPL_DLL VSIFilesystemHandler
     379             : {
     380             : 
     381             :   public:
     382       32802 :     virtual ~VSIFilesystemHandler() = default;
     383             : 
     384             :     static VSIVirtualHandleUniquePtr
     385             :     OpenStatic(const char *pszFilename, const char *pszAccess,
     386             :                bool bSetError = false, CSLConstList papszOptions = nullptr);
     387             : 
     388             :     virtual VSIVirtualHandleUniquePtr
     389             :     Open(const char *pszFilename, const char *pszAccess, bool bSetError = false,
     390             :          CSLConstList papszOptions = nullptr) = 0;
     391             : 
     392             :     virtual VSIVirtualHandleUniquePtr
     393             :     CreateOnlyVisibleAtCloseTime(const char *pszFilename,
     394             :                                  bool bEmulationAllowed,
     395             :                                  CSLConstList papszOptions);
     396             : 
     397             :     virtual int Stat(const char *pszFilename, VSIStatBufL *pStatBuf,
     398             :                      int nFlags) = 0;
     399             : 
     400           4 :     virtual int Unlink(const char *pszFilename)
     401             :     {
     402             :         (void)pszFilename;
     403           4 :         errno = ENOENT;
     404           4 :         return -1;
     405             :     }
     406             : 
     407             :     virtual int *UnlinkBatch(CSLConstList papszFiles);
     408             : 
     409           0 :     virtual int Mkdir(const char *pszDirname, long nMode)
     410             :     {
     411             :         (void)pszDirname;
     412             :         (void)nMode;
     413           0 :         errno = ENOENT;
     414           0 :         return -1;
     415             :     }
     416             : 
     417           0 :     virtual int Rmdir(const char *pszDirname)
     418             :     {
     419             :         (void)pszDirname;
     420           0 :         errno = ENOENT;
     421           0 :         return -1;
     422             :     }
     423             : 
     424             :     virtual int RmdirRecursive(const char *pszDirname);
     425             : 
     426           5 :     char **ReadDir(const char *pszDirname)
     427             :     {
     428           5 :         return ReadDirEx(pszDirname, 0);
     429             :     }
     430             : 
     431           4 :     virtual char **ReadDirEx(const char * /*pszDirname*/, int /* nMaxFiles */)
     432             :     {
     433           4 :         return nullptr;
     434             :     }
     435             : 
     436       82573 :     virtual char **SiblingFiles(const char * /*pszFilename*/)
     437             :     {
     438       82573 :         return nullptr;
     439             :     }
     440             : 
     441           0 :     virtual int Rename(const char *oldpath, const char *newpath,
     442             :                        GDALProgressFunc pProgressFunc, void *pProgressData)
     443             :     {
     444             :         (void)oldpath;
     445             :         (void)newpath;
     446             :         (void)pProgressFunc;
     447             :         (void)pProgressData;
     448           0 :         errno = ENOENT;
     449           0 :         return -1;
     450             :     }
     451             : 
     452       30855 :     virtual int IsCaseSensitive(const char *pszFilename)
     453             :     {
     454             :         (void)pszFilename;
     455       30855 :         return TRUE;
     456             :     }
     457             : 
     458           0 :     virtual GIntBig GetDiskFreeSpace(const char * /* pszDirname */)
     459             :     {
     460           0 :         return -1;
     461             :     }
     462             : 
     463           0 :     virtual int SupportsSparseFiles(const char * /* pszPath */)
     464             :     {
     465           0 :         return FALSE;
     466             :     }
     467             : 
     468       15639 :     virtual int HasOptimizedReadMultiRange(const char * /* pszPath */)
     469             :     {
     470       15639 :         return FALSE;
     471             :     }
     472             : 
     473           1 :     virtual const char *GetActualURL(const char * /*pszFilename*/)
     474             :     {
     475           1 :         return nullptr;
     476             :     }
     477             : 
     478          14 :     virtual const char *GetOptions()
     479             :     {
     480          14 :         return nullptr;
     481             :     }
     482             : 
     483           1 :     virtual char *GetSignedURL(const char * /*pszFilename*/,
     484             :                                CSLConstList /* papszOptions */)
     485             :     {
     486           1 :         return nullptr;
     487             :     }
     488             : 
     489             :     virtual bool Sync(const char *pszSource, const char *pszTarget,
     490             :                       const char *const *papszOptions,
     491             :                       GDALProgressFunc pProgressFunc, void *pProgressData,
     492             :                       char ***ppapszOutputs);
     493             : 
     494             :     virtual int CopyFile(const char *pszSource, const char *pszTarget,
     495             :                          VSILFILE *fpSource, vsi_l_offset nSourceSize,
     496             :                          const char *const *papszOptions,
     497             :                          GDALProgressFunc pProgressFunc, void *pProgressData);
     498             : 
     499             :     virtual int
     500             :     CopyFileRestartable(const char *pszSource, const char *pszTarget,
     501             :                         const char *pszInputPayload, char **ppszOutputPayload,
     502             :                         CSLConstList papszOptions,
     503             :                         GDALProgressFunc pProgressFunc, void *pProgressData);
     504             : 
     505             :     virtual VSIDIR *OpenDir(const char *pszPath, int nRecurseDepth,
     506             :                             const char *const *papszOptions);
     507             : 
     508             :     virtual char **GetFileMetadata(const char *pszFilename,
     509             :                                    const char *pszDomain,
     510             :                                    CSLConstList papszOptions);
     511             : 
     512             :     virtual bool SetFileMetadata(const char *pszFilename,
     513             :                                  CSLConstList papszMetadata,
     514             :                                  const char *pszDomain,
     515             :                                  CSLConstList papszOptions);
     516             : 
     517             :     virtual bool
     518             :     MultipartUploadGetCapabilities(int *pbNonSequentialUploadSupported,
     519             :                                    int *pbParallelUploadSupported,
     520             :                                    int *pbAbortSupported, size_t *pnMinPartSize,
     521             :                                    size_t *pnMaxPartSize, int *pnMaxPartCount);
     522             : 
     523             :     virtual char *MultipartUploadStart(const char *pszFilename,
     524             :                                        CSLConstList papszOptions);
     525             : 
     526             :     virtual char *MultipartUploadAddPart(const char *pszFilename,
     527             :                                          const char *pszUploadId,
     528             :                                          int nPartNumber,
     529             :                                          vsi_l_offset nFileOffset,
     530             :                                          const void *pData, size_t nDataLength,
     531             :                                          CSLConstList papszOptions);
     532             : 
     533             :     virtual bool
     534             :     MultipartUploadEnd(const char *pszFilename, const char *pszUploadId,
     535             :                        size_t nPartIdsCount, const char *const *apszPartIds,
     536             :                        vsi_l_offset nTotalSize, CSLConstList papszOptions);
     537             : 
     538             :     virtual bool MultipartUploadAbort(const char *pszFilename,
     539             :                                       const char *pszUploadId,
     540             :                                       CSLConstList papszOptions);
     541             : 
     542           0 :     virtual bool AbortPendingUploads(const char * /*pszFilename*/)
     543             :     {
     544           0 :         return true;
     545             :     }
     546             : 
     547             :     virtual std::string
     548       33199 :     GetStreamingFilename(const std::string &osFilename) const
     549             :     {
     550       33199 :         return osFilename;
     551             :     }
     552             : 
     553             :     virtual std::string
     554        2341 :     GetNonStreamingFilename(const std::string &osFilename) const
     555             :     {
     556        2341 :         return osFilename;
     557             :     }
     558             : 
     559             :     /** Return the canonical filename.
     560             :      *
     561             :      * May be implemented by case-insensitive filesystems
     562             :      * (currently Win32 and MacOSX)
     563             :      * to return the filename with its actual case (i.e. the one that would
     564             :      * be used when listing the content of the directory).
     565             :      */
     566             :     virtual std::string
     567         114 :     GetCanonicalFilename(const std::string &osFilename) const
     568             :     {
     569         114 :         return osFilename;
     570             :     }
     571             : 
     572        2254 :     virtual bool IsLocal(const char * /* pszPath */) const
     573             :     {
     574        2254 :         return true;
     575             :     }
     576             : 
     577           5 :     virtual bool IsArchive(const char * /* pszPath */) const
     578             :     {
     579           5 :         return false;
     580             :     }
     581             : 
     582          57 :     virtual bool SupportsSequentialWrite(const char * /* pszPath */,
     583             :                                          bool /* bAllowLocalTempFile */)
     584             :     {
     585          57 :         return true;
     586             :     }
     587             : 
     588         301 :     virtual bool SupportsRandomWrite(const char * /* pszPath */,
     589             :                                      bool /* bAllowLocalTempFile */)
     590             :     {
     591         301 :         return true;
     592             :     }
     593             : 
     594          43 :     virtual bool SupportsRead(const char * /* pszPath */)
     595             :     {
     596          43 :         return true;
     597             :     }
     598             : 
     599           2 :     virtual VSIFilesystemHandler *Duplicate(const char * /* pszPrefix */)
     600             :     {
     601           2 :         CPLError(CE_Failure, CPLE_NotSupported,
     602             :                  "Duplicate() not supported on this file "
     603             :                  "system");
     604           2 :         return nullptr;
     605             :     }
     606             : 
     607             :     /** Return the directory separator.
     608             :      *
     609             :      * Default is forward slash. The only exception currently is the Windows
     610             :      * file system which returns anti-slash, unless the specified path is of the
     611             :      * form "{drive_letter}:/{rest_of_the_path}".
     612             :      */
     613      960134 :     virtual const char *GetDirectorySeparator(CPL_UNUSED const char *pszPath)
     614             :     {
     615      960134 :         return "/";
     616             :     }
     617             : 
     618             :     /** Returns a hint about the path that this file system
     619             :      * could (potentially) recognize given the input path.
     620             :      *
     621             :      * e.g. /vsizip/ will return "/vsizip/my.zip" if provided with "my.zip",
     622             :      * /vsicurl/ will return "/vsicurl/https://example.com" if provided with
     623             :      * "https://example.com", /vsis3/ will return "/vsis3/bucket/object" if
     624             :      * provided with "s3://bucket/object", etc.
     625             :      *
     626             :      * Returns an empty string if the input path cannot easily be identified
     627             :      * as a potential match for the file system.
     628             :      */
     629             :     virtual std::string
     630      143444 :     GetHintForPotentiallyRecognizedPath(const std::string &osPath)
     631             :     {
     632             :         (void)osPath;
     633      143444 :         return std::string();
     634             :     }
     635             : };
     636             : #endif /* #ifndef DOXYGEN_SKIP */
     637             : 
     638             : /************************************************************************/
     639             : /*                            VSIFileManager                            */
     640             : /************************************************************************/
     641             : 
     642             : #ifndef DOXYGEN_SKIP
     643        2939 : class CPL_DLL VSIFileManager
     644             : {
     645             :   private:
     646             :     std::shared_ptr<VSIFilesystemHandler> m_poDefaultHandler{};
     647             :     std::map<std::string, std::shared_ptr<VSIFilesystemHandler>>
     648             :         m_apoHandlers{};
     649             : 
     650             :     VSIFileManager();
     651             : 
     652             :     static VSIFileManager *Get();
     653             : 
     654             :     CPL_DISALLOW_COPY_ASSIGN(VSIFileManager)
     655             : 
     656             :   public:
     657             :     ~VSIFileManager();
     658             : 
     659             :     static VSIFilesystemHandler *GetHandler(const char *);
     660             :     static void InstallHandler(const std::string &osPrefix,
     661             :                                const std::shared_ptr<VSIFilesystemHandler> &);
     662             :     static void InstallHandler(const std::string &osPrefix,
     663             :                                VSIFilesystemHandler *)
     664             :         CPL_WARN_DEPRECATED("Use version with std::shared_ptr<> instead");
     665             :     static void RemoveHandler(const std::string &osPrefix);
     666             : 
     667             :     static char **GetPrefixes();
     668             : };
     669             : #endif /* #ifndef DOXYGEN_SKIP */
     670             : 
     671             : /************************************************************************/
     672             : /* ==================================================================== */
     673             : /*                       VSIArchiveFilesystemHandler                   */
     674             : /* ==================================================================== */
     675             : /************************************************************************/
     676             : 
     677             : #ifndef DOXYGEN_SKIP
     678             : 
     679        1548 : class VSIArchiveEntryFileOffset
     680             : {
     681             :   public:
     682             :     virtual ~VSIArchiveEntryFileOffset();
     683             : };
     684             : 
     685             : class VSIArchiveEntry
     686             : {
     687             :   public:
     688             :     std::string fileName{};
     689             :     vsi_l_offset uncompressed_size = 0;
     690             :     std::unique_ptr<VSIArchiveEntryFileOffset> file_pos{};
     691             :     bool bIsDir = false;
     692             :     GIntBig nModifiedTime = 0;
     693             : };
     694             : 
     695          75 : class VSIArchiveContent
     696             : {
     697             :   public:
     698             :     time_t mTime = 0;
     699             :     vsi_l_offset nFileSize = 0;
     700             :     std::vector<VSIArchiveEntry> entries{};
     701             : 
     702             :     // Store list of child indices for each directory
     703             :     using DirectoryChildren = std::vector<int>;
     704             : 
     705             :     std::map<std::string, DirectoryChildren> dirIndex{};
     706             : 
     707         230 :     VSIArchiveContent() = default;
     708             : 
     709             :     ~VSIArchiveContent();
     710             : 
     711             :   private:
     712             :     CPL_DISALLOW_COPY_ASSIGN(VSIArchiveContent)
     713             : };
     714             : 
     715        5528 : class VSIArchiveReader
     716             : {
     717             :   public:
     718             :     virtual ~VSIArchiveReader();
     719             : 
     720             :     virtual int GotoFirstFile() = 0;
     721             :     virtual int GotoNextFile() = 0;
     722             :     virtual VSIArchiveEntryFileOffset *GetFileOffset() = 0;
     723             :     virtual GUIntBig GetFileSize() = 0;
     724             :     virtual CPLString GetFileName() = 0;
     725             :     virtual GIntBig GetModifiedTime() = 0;
     726             :     virtual int GotoFileOffset(VSIArchiveEntryFileOffset *pOffset) = 0;
     727             : };
     728             : 
     729        5878 : class VSIArchiveFilesystemHandler /* non final */ : public VSIFilesystemHandler
     730             : {
     731             :     CPL_DISALLOW_COPY_ASSIGN(VSIArchiveFilesystemHandler)
     732             : 
     733             :     bool FindFileInArchive(const char *archiveFilename,
     734             :                            const char *fileInArchiveName,
     735             :                            const VSIArchiveEntry **archiveEntry);
     736             : 
     737             :   protected:
     738             :     mutable std::recursive_mutex oMutex{};
     739             : 
     740             :     /* We use a cache that contains the list of files contained in a VSIArchive
     741             :      * file as */
     742             :     /* unarchive.c is quite inefficient in listing them. This speeds up access
     743             :      * to VSIArchive files */
     744             :     /* containing ~1000 files like a CADRG product */
     745             :     std::map<CPLString, std::unique_ptr<VSIArchiveContent>> oFileList{};
     746             : 
     747             :     virtual const char *GetPrefix() const = 0;
     748             :     virtual std::vector<CPLString> GetExtensions() const = 0;
     749             :     virtual std::unique_ptr<VSIArchiveReader>
     750             :     CreateReader(const char *pszArchiveFileName) = 0;
     751             : 
     752             :   public:
     753             :     VSIArchiveFilesystemHandler();
     754             :     ~VSIArchiveFilesystemHandler() override;
     755             : 
     756             :     int Stat(const char *pszFilename, VSIStatBufL *pStatBuf,
     757             :              int nFlags) override;
     758             :     char **ReadDirEx(const char *pszDirname, int nMaxFiles) override;
     759             : 
     760             :     virtual const VSIArchiveContent *
     761             :     GetContentOfArchive(const char *archiveFilename,
     762             :                         VSIArchiveReader *poReader = nullptr);
     763             :     virtual std::unique_ptr<char, VSIFreeReleaser>
     764             :     SplitFilename(const char *pszFilename, CPLString &osFileInArchive,
     765             :                   bool bCheckMainFileExists, bool bSetError) const;
     766             :     virtual std::unique_ptr<VSIArchiveReader>
     767             :     OpenArchiveFile(const char *archiveFilename, const char *fileInArchiveName);
     768             : 
     769             :     bool IsLocal(const char *pszPath) const override;
     770             : 
     771             :     bool IsArchive(const char *pszPath) const override;
     772             : 
     773           0 :     bool SupportsSequentialWrite(const char * /* pszPath */,
     774             :                                  bool /* bAllowLocalTempFile */) override
     775             :     {
     776           0 :         return false;
     777             :     }
     778             : 
     779           0 :     bool SupportsRandomWrite(const char * /* pszPath */,
     780             :                              bool /* bAllowLocalTempFile */) override
     781             :     {
     782           0 :         return false;
     783             :     }
     784             : 
     785             :     std::string
     786             :     GetHintForPotentiallyRecognizedPath(const std::string &osPath) override;
     787             : };
     788             : 
     789             : /************************************************************************/
     790             : /*                                VSIDIR                                */
     791             : /************************************************************************/
     792             : 
     793             : struct CPL_DLL VSIDIR
     794             : {
     795        3752 :     VSIDIR() = default;
     796             :     virtual ~VSIDIR();
     797             : 
     798             :     virtual const VSIDIREntry *NextDirEntry() = 0;
     799             : 
     800             :   private:
     801             :     VSIDIR(const VSIDIR &) = delete;
     802             :     VSIDIR &operator=(const VSIDIR &) = delete;
     803             : };
     804             : 
     805             : #endif /* #ifndef DOXYGEN_SKIP */
     806             : 
     807             : VSIVirtualHandle CPL_DLL *
     808             : VSICreateBufferedReaderHandle(VSIVirtualHandle *poBaseHandle);
     809             : VSIVirtualHandle *
     810             : VSICreateBufferedReaderHandle(VSIVirtualHandle *poBaseHandle,
     811             :                               const GByte *pabyBeginningContent,
     812             :                               vsi_l_offset nCheatFileSize);
     813             : constexpr int VSI_CACHED_DEFAULT_CHUNK_SIZE = 32768;
     814             : VSIVirtualHandle CPL_DLL *
     815             : VSICreateCachedFile(VSIVirtualHandle *poBaseHandle,
     816             :                     size_t nChunkSize = VSI_CACHED_DEFAULT_CHUNK_SIZE,
     817             :                     size_t nCacheSize = 0);
     818             : 
     819             : const int CPL_DEFLATE_TYPE_GZIP = 0;
     820             : const int CPL_DEFLATE_TYPE_ZLIB = 1;
     821             : const int CPL_DEFLATE_TYPE_RAW_DEFLATE = 2;
     822             : VSIVirtualHandle CPL_DLL *VSICreateGZipWritable(VSIVirtualHandle *poBaseHandle,
     823             :                                                 int nDeflateType,
     824             :                                                 int bAutoCloseBaseHandle);
     825             : 
     826             : VSIVirtualHandle *VSICreateGZipWritable(VSIVirtualHandle *poBaseHandle,
     827             :                                         int nDeflateType,
     828             :                                         bool bAutoCloseBaseHandle, int nThreads,
     829             :                                         size_t nChunkSize,
     830             :                                         size_t nSOZIPIndexEltSize,
     831             :                                         std::vector<uint8_t> *panSOZIPIndex);
     832             : 
     833             : VSIVirtualHandle *
     834             : VSICreateUploadOnCloseFile(VSIVirtualHandleUniquePtr &&poWritableHandle,
     835             :                            VSIVirtualHandleUniquePtr &&poTmpFile,
     836             :                            const std::string &osTmpFilename);
     837             : 
     838             : #endif /* ndef CPL_VSI_VIRTUAL_H_INCLUDED */

Generated by: LCOV version 1.14