LCOV - code coverage report
Current view: top level - port - cpl_vsi_virtual.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 89 134 66.4 %
Date: 2026-02-03 04:34:44 Functions: 47 72 65.3 %

          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       37918 :     inline int Seek(int &&nOffset, int nWhence)
      55             :     {
      56       37918 :         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       84809 :     Seek(T nOffset, int nWhence)
      69             :     {
      70       84809 :         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             :     virtual size_t Read(void *pBuffer, size_t nBytes) = 0;
      91             :     virtual int ReadMultiRange(int nRanges, void **ppData,
      92             :                                const vsi_l_offset *panOffsets,
      93             :                                const size_t *panSizes);
      94             : 
      95             :     /** This method is called when code plans to access soon one or several
      96             :      * ranges in a file. Some file systems may be able to use this hint to
      97             :      * for example asynchronously start such requests.
      98             :      *
      99             :      * Offsets may be given in a non-increasing order, and may potentially
     100             :      * overlap.
     101             :      *
     102             :      * @param nRanges Size of the panOffsets and panSizes arrays.
     103             :      * @param panOffsets Array containing the start offset of each range.
     104             :      * @param panSizes Array containing the size (in bytes) of each range.
     105             :      * @since GDAL 3.7
     106             :      */
     107          92 :     virtual void AdviseRead(CPL_UNUSED int nRanges,
     108             :                             CPL_UNUSED const vsi_l_offset *panOffsets,
     109             :                             CPL_UNUSED const size_t *panSizes)
     110             :     {
     111          92 :     }
     112             : 
     113             :     /** Return the total maximum number of bytes that AdviseRead() can handle
     114             :      * at once.
     115             :      *
     116             :      * Some AdviseRead() implementations may give up if the sum of the values
     117             :      * in the panSizes[] array provided to AdviseRead() exceeds a limit.
     118             :      *
     119             :      * Callers might use that threshold to optimize the efficiency of
     120             :      * AdviseRead().
     121             :      *
     122             :      * A returned value of 0 indicates a unknown limit.
     123             :      * @since GDAL 3.9
     124             :      */
     125         220 :     virtual size_t GetAdviseReadTotalBytesLimit() const
     126             :     {
     127         220 :         return 0;
     128             :     }
     129             : 
     130             :     virtual size_t Write(const void *pBuffer, size_t nBytes) = 0;
     131             :     size_t Write(const void *pBuffer, size_t nSize, size_t nCount);
     132             : 
     133             :     int Printf(CPL_FORMAT_STRING(const char *pszFormat), ...)
     134             :         CPL_PRINT_FUNC_FORMAT(2, 3);
     135             : 
     136             :     virtual void ClearErr() = 0;
     137             : 
     138             :     virtual int Eof() = 0;
     139             : 
     140             :     virtual int Error() = 0;
     141             : 
     142       48813 :     virtual int Flush()
     143             :     {
     144       48813 :         return 0;
     145             :     }
     146             : 
     147             :     virtual int Close() = 0;
     148             :     // Base implementation that only supports file extension.
     149             :     virtual int Truncate(vsi_l_offset nNewSize);
     150             : 
     151           9 :     virtual void *GetNativeFileDescriptor()
     152             :     {
     153           9 :         return nullptr;
     154             :     }
     155             : 
     156         154 :     virtual VSIRangeStatus GetRangeStatus(CPL_UNUSED vsi_l_offset nOffset,
     157             :                                           CPL_UNUSED vsi_l_offset nLength)
     158             :     {
     159         154 :         return VSI_RANGE_STATUS_UNKNOWN;
     160             :     }
     161             : 
     162             :     virtual bool HasPRead() const;
     163             :     virtual size_t PRead(void *pBuffer, size_t nSize,
     164             :                          vsi_l_offset nOffset) const;
     165             : 
     166             :     /** Ask current operations to be interrupted.
     167             :      * Implementations must be thread-safe, as this will typically be called
     168             :      * from another thread than the active one for this file.
     169             :      */
     170           7 :     virtual void Interrupt()
     171             :     {
     172           7 :     }
     173             : 
     174             :     /** For a file created with CreateOnlyVisibleAtCloseTime(), ask for the
     175             :      * file to not be created at all (if possible)
     176             :      */
     177          88 :     virtual void CancelCreation()
     178             :     {
     179          88 :     }
     180             : 
     181             :     // NOTE: when adding new methods, besides the "actual" implementations,
     182             :     // also consider the VSICachedFile and VSIVirtualHandleOnlyVisibleAtCloseTime one.
     183             : 
     184      356543 :     virtual ~VSIVirtualHandle()
     185      356543 :     {
     186      356543 :     }
     187             : };
     188             : 
     189             : /************************************************************************/
     190             : /*                        VSIVirtualHandleCloser                        */
     191             : /************************************************************************/
     192             : 
     193             : /** Helper close to use with a std:unique_ptr<VSIVirtualHandle>,
     194             :  *  such as VSIVirtualHandleUniquePtr. */
     195             : struct VSIVirtualHandleCloser
     196             : 
     197             : {
     198             :     /** Operator () that closes and deletes the file handle. */
     199       45446 :     void operator()(VSIVirtualHandle *poHandle)
     200             :     {
     201       45446 :         if (poHandle)
     202             :         {
     203       45347 :             poHandle->Close();
     204       45223 :             delete poHandle;
     205             :         }
     206       45733 :     }
     207             : };
     208             : 
     209             : /** Unique pointer of VSIVirtualHandle that calls the Close() method */
     210             : typedef std::unique_ptr<VSIVirtualHandle, VSIVirtualHandleCloser>
     211             :     VSIVirtualHandleUniquePtr;
     212             : 
     213             : /************************************************************************/
     214             : /*                          VSIProxyFileHandle                          */
     215             : /************************************************************************/
     216             : 
     217             : #ifndef DOXYGEN_SKIP
     218             : class VSIProxyFileHandle /* non final */ : public VSIVirtualHandle
     219             : {
     220             :   protected:
     221             :     VSIVirtualHandleUniquePtr m_nativeHandle{};
     222             : 
     223             :   public:
     224         224 :     explicit VSIProxyFileHandle(VSIVirtualHandleUniquePtr &&nativeHandle)
     225         224 :         : m_nativeHandle(std::move(nativeHandle))
     226             :     {
     227         224 :     }
     228             : 
     229         976 :     int Seek(vsi_l_offset nOffset, int nWhence) override
     230             :     {
     231         976 :         return m_nativeHandle->Seek(nOffset, nWhence);
     232             :     }
     233             : 
     234         890 :     vsi_l_offset Tell() override
     235             :     {
     236         890 :         return m_nativeHandle->Tell();
     237             :     }
     238             : 
     239        1187 :     size_t Read(void *pBuffer, size_t nBytes) override
     240             :     {
     241        1187 :         return m_nativeHandle->Read(pBuffer, nBytes);
     242             :     }
     243             : 
     244           0 :     int ReadMultiRange(int nRanges, void **ppData,
     245             :                        const vsi_l_offset *panOffsets,
     246             :                        const size_t *panSizes) override
     247             :     {
     248           0 :         return m_nativeHandle->ReadMultiRange(nRanges, ppData, panOffsets,
     249           0 :                                               panSizes);
     250             :     }
     251             : 
     252           0 :     void AdviseRead(int nRanges, const vsi_l_offset *panOffsets,
     253             :                     const size_t *panSizes) override
     254             :     {
     255           0 :         return m_nativeHandle->AdviseRead(nRanges, panOffsets, panSizes);
     256             :     }
     257             : 
     258           0 :     size_t GetAdviseReadTotalBytesLimit() const override
     259             :     {
     260           0 :         return m_nativeHandle->GetAdviseReadTotalBytesLimit();
     261             :     }
     262             : 
     263        5352 :     size_t Write(const void *pBuffer, size_t nBytes) override
     264             :     {
     265        5352 :         return m_nativeHandle->Write(pBuffer, nBytes);
     266             :     }
     267             : 
     268           0 :     void ClearErr() override
     269             :     {
     270           0 :         return m_nativeHandle->ClearErr();
     271             :     }
     272             : 
     273           0 :     int Eof() override
     274             :     {
     275           0 :         return m_nativeHandle->Eof();
     276             :     }
     277             : 
     278           0 :     int Error() override
     279             :     {
     280           0 :         return m_nativeHandle->Error();
     281             :     }
     282             : 
     283           2 :     int Flush() override
     284             :     {
     285           2 :         return m_nativeHandle->Flush();
     286             :     }
     287             : 
     288         224 :     int Close() override
     289             :     {
     290         224 :         return m_nativeHandle->Close();
     291             :     }
     292             : 
     293           0 :     int Truncate(vsi_l_offset nNewSize) override
     294             :     {
     295           0 :         return m_nativeHandle->Truncate(nNewSize);
     296             :     }
     297             : 
     298           0 :     void *GetNativeFileDescriptor() override
     299             :     {
     300           0 :         return m_nativeHandle->GetNativeFileDescriptor();
     301             :     }
     302             : 
     303           0 :     VSIRangeStatus GetRangeStatus(vsi_l_offset nOffset,
     304             :                                   vsi_l_offset nLength) override
     305             :     {
     306           0 :         return m_nativeHandle->GetRangeStatus(nOffset, nLength);
     307             :     }
     308             : 
     309           0 :     bool HasPRead() const override
     310             :     {
     311           0 :         return m_nativeHandle->HasPRead();
     312             :     }
     313             : 
     314           0 :     size_t PRead(void *pBuffer, size_t nSize,
     315             :                  vsi_l_offset nOffset) const override
     316             :     {
     317           0 :         return m_nativeHandle->PRead(pBuffer, nSize, nOffset);
     318             :     }
     319             : 
     320           0 :     void Interrupt() override
     321             :     {
     322           0 :         m_nativeHandle->Interrupt();
     323           0 :     }
     324             : 
     325             :     void CancelCreation() override;
     326             : };
     327             : #endif
     328             : 
     329             : /************************************************************************/
     330             : /*                         VSIFilesystemHandler                         */
     331             : /************************************************************************/
     332             : 
     333             : #ifndef DOXYGEN_SKIP
     334             : class CPL_DLL VSIFilesystemHandler
     335             : {
     336             : 
     337             :   public:
     338       32657 :     virtual ~VSIFilesystemHandler() = default;
     339             : 
     340             :     static VSIVirtualHandleUniquePtr
     341             :     OpenStatic(const char *pszFilename, const char *pszAccess,
     342             :                bool bSetError = false, CSLConstList papszOptions = nullptr);
     343             : 
     344             :     virtual VSIVirtualHandleUniquePtr
     345             :     Open(const char *pszFilename, const char *pszAccess, bool bSetError = false,
     346             :          CSLConstList papszOptions = nullptr) = 0;
     347             : 
     348             :     virtual VSIVirtualHandleUniquePtr
     349             :     CreateOnlyVisibleAtCloseTime(const char *pszFilename,
     350             :                                  bool bEmulationAllowed,
     351             :                                  CSLConstList papszOptions);
     352             : 
     353             :     virtual int Stat(const char *pszFilename, VSIStatBufL *pStatBuf,
     354             :                      int nFlags) = 0;
     355             : 
     356           2 :     virtual int Unlink(const char *pszFilename)
     357             :     {
     358             :         (void)pszFilename;
     359           2 :         errno = ENOENT;
     360           2 :         return -1;
     361             :     }
     362             : 
     363             :     virtual int *UnlinkBatch(CSLConstList papszFiles);
     364             : 
     365           0 :     virtual int Mkdir(const char *pszDirname, long nMode)
     366             :     {
     367             :         (void)pszDirname;
     368             :         (void)nMode;
     369           0 :         errno = ENOENT;
     370           0 :         return -1;
     371             :     }
     372             : 
     373           0 :     virtual int Rmdir(const char *pszDirname)
     374             :     {
     375             :         (void)pszDirname;
     376           0 :         errno = ENOENT;
     377           0 :         return -1;
     378             :     }
     379             : 
     380             :     virtual int RmdirRecursive(const char *pszDirname);
     381             : 
     382           5 :     char **ReadDir(const char *pszDirname)
     383             :     {
     384           5 :         return ReadDirEx(pszDirname, 0);
     385             :     }
     386             : 
     387           3 :     virtual char **ReadDirEx(const char * /*pszDirname*/, int /* nMaxFiles */)
     388             :     {
     389           3 :         return nullptr;
     390             :     }
     391             : 
     392       81912 :     virtual char **SiblingFiles(const char * /*pszFilename*/)
     393             :     {
     394       81912 :         return nullptr;
     395             :     }
     396             : 
     397           0 :     virtual int Rename(const char *oldpath, const char *newpath,
     398             :                        GDALProgressFunc pProgressFunc, void *pProgressData)
     399             :     {
     400             :         (void)oldpath;
     401             :         (void)newpath;
     402             :         (void)pProgressFunc;
     403             :         (void)pProgressData;
     404           0 :         errno = ENOENT;
     405           0 :         return -1;
     406             :     }
     407             : 
     408       29194 :     virtual int IsCaseSensitive(const char *pszFilename)
     409             :     {
     410             :         (void)pszFilename;
     411       29194 :         return TRUE;
     412             :     }
     413             : 
     414           0 :     virtual GIntBig GetDiskFreeSpace(const char * /* pszDirname */)
     415             :     {
     416           0 :         return -1;
     417             :     }
     418             : 
     419           0 :     virtual int SupportsSparseFiles(const char * /* pszPath */)
     420             :     {
     421           0 :         return FALSE;
     422             :     }
     423             : 
     424       15583 :     virtual int HasOptimizedReadMultiRange(const char * /* pszPath */)
     425             :     {
     426       15583 :         return FALSE;
     427             :     }
     428             : 
     429           1 :     virtual const char *GetActualURL(const char * /*pszFilename*/)
     430             :     {
     431           1 :         return nullptr;
     432             :     }
     433             : 
     434          14 :     virtual const char *GetOptions()
     435             :     {
     436          14 :         return nullptr;
     437             :     }
     438             : 
     439           1 :     virtual char *GetSignedURL(const char * /*pszFilename*/,
     440             :                                CSLConstList /* papszOptions */)
     441             :     {
     442           1 :         return nullptr;
     443             :     }
     444             : 
     445             :     virtual bool Sync(const char *pszSource, const char *pszTarget,
     446             :                       const char *const *papszOptions,
     447             :                       GDALProgressFunc pProgressFunc, void *pProgressData,
     448             :                       char ***ppapszOutputs);
     449             : 
     450             :     virtual int CopyFile(const char *pszSource, const char *pszTarget,
     451             :                          VSILFILE *fpSource, vsi_l_offset nSourceSize,
     452             :                          const char *const *papszOptions,
     453             :                          GDALProgressFunc pProgressFunc, void *pProgressData);
     454             : 
     455             :     virtual int
     456             :     CopyFileRestartable(const char *pszSource, const char *pszTarget,
     457             :                         const char *pszInputPayload, char **ppszOutputPayload,
     458             :                         CSLConstList papszOptions,
     459             :                         GDALProgressFunc pProgressFunc, void *pProgressData);
     460             : 
     461             :     virtual VSIDIR *OpenDir(const char *pszPath, int nRecurseDepth,
     462             :                             const char *const *papszOptions);
     463             : 
     464             :     virtual char **GetFileMetadata(const char *pszFilename,
     465             :                                    const char *pszDomain,
     466             :                                    CSLConstList papszOptions);
     467             : 
     468             :     virtual bool SetFileMetadata(const char *pszFilename,
     469             :                                  CSLConstList papszMetadata,
     470             :                                  const char *pszDomain,
     471             :                                  CSLConstList papszOptions);
     472             : 
     473             :     virtual bool
     474             :     MultipartUploadGetCapabilities(int *pbNonSequentialUploadSupported,
     475             :                                    int *pbParallelUploadSupported,
     476             :                                    int *pbAbortSupported, size_t *pnMinPartSize,
     477             :                                    size_t *pnMaxPartSize, int *pnMaxPartCount);
     478             : 
     479             :     virtual char *MultipartUploadStart(const char *pszFilename,
     480             :                                        CSLConstList papszOptions);
     481             : 
     482             :     virtual char *MultipartUploadAddPart(const char *pszFilename,
     483             :                                          const char *pszUploadId,
     484             :                                          int nPartNumber,
     485             :                                          vsi_l_offset nFileOffset,
     486             :                                          const void *pData, size_t nDataLength,
     487             :                                          CSLConstList papszOptions);
     488             : 
     489             :     virtual bool
     490             :     MultipartUploadEnd(const char *pszFilename, const char *pszUploadId,
     491             :                        size_t nPartIdsCount, const char *const *apszPartIds,
     492             :                        vsi_l_offset nTotalSize, CSLConstList papszOptions);
     493             : 
     494             :     virtual bool MultipartUploadAbort(const char *pszFilename,
     495             :                                       const char *pszUploadId,
     496             :                                       CSLConstList papszOptions);
     497             : 
     498           0 :     virtual bool AbortPendingUploads(const char * /*pszFilename*/)
     499             :     {
     500           0 :         return true;
     501             :     }
     502             : 
     503             :     virtual std::string
     504       30000 :     GetStreamingFilename(const std::string &osFilename) const
     505             :     {
     506       30000 :         return osFilename;
     507             :     }
     508             : 
     509             :     virtual std::string
     510        1506 :     GetNonStreamingFilename(const std::string &osFilename) const
     511             :     {
     512        1506 :         return osFilename;
     513             :     }
     514             : 
     515             :     /** Return the canonical filename.
     516             :      *
     517             :      * May be implemented by case-insensitive filesystems
     518             :      * (currently Win32 and MacOSX)
     519             :      * to return the filename with its actual case (i.e. the one that would
     520             :      * be used when listing the content of the directory).
     521             :      */
     522             :     virtual std::string
     523         256 :     GetCanonicalFilename(const std::string &osFilename) const
     524             :     {
     525         256 :         return osFilename;
     526             :     }
     527             : 
     528         118 :     virtual bool IsLocal(const char * /* pszPath */) const
     529             :     {
     530         118 :         return true;
     531             :     }
     532             : 
     533           5 :     virtual bool IsArchive(const char * /* pszPath */) const
     534             :     {
     535           5 :         return false;
     536             :     }
     537             : 
     538          57 :     virtual bool SupportsSequentialWrite(const char * /* pszPath */,
     539             :                                          bool /* bAllowLocalTempFile */)
     540             :     {
     541          57 :         return true;
     542             :     }
     543             : 
     544         301 :     virtual bool SupportsRandomWrite(const char * /* pszPath */,
     545             :                                      bool /* bAllowLocalTempFile */)
     546             :     {
     547         301 :         return true;
     548             :     }
     549             : 
     550          43 :     virtual bool SupportsRead(const char * /* pszPath */)
     551             :     {
     552          43 :         return true;
     553             :     }
     554             : 
     555           2 :     virtual VSIFilesystemHandler *Duplicate(const char * /* pszPrefix */)
     556             :     {
     557           2 :         CPLError(CE_Failure, CPLE_NotSupported,
     558             :                  "Duplicate() not supported on this file "
     559             :                  "system");
     560           2 :         return nullptr;
     561             :     }
     562             : 
     563             :     /** Return the directory separator.
     564             :      *
     565             :      * Default is forward slash. The only exception currently is the Windows
     566             :      * file system which returns anti-slash, unless the specified path is of the
     567             :      * form "{drive_letter}:/{rest_of_the_path}".
     568             :      */
     569      948446 :     virtual const char *GetDirectorySeparator(CPL_UNUSED const char *pszPath)
     570             :     {
     571      948446 :         return "/";
     572             :     }
     573             : };
     574             : #endif /* #ifndef DOXYGEN_SKIP */
     575             : 
     576             : /************************************************************************/
     577             : /*                            VSIFileManager                            */
     578             : /************************************************************************/
     579             : 
     580             : #ifndef DOXYGEN_SKIP
     581        2914 : class CPL_DLL VSIFileManager
     582             : {
     583             :   private:
     584             :     std::shared_ptr<VSIFilesystemHandler> m_poDefaultHandler{};
     585             :     std::map<std::string, std::shared_ptr<VSIFilesystemHandler>>
     586             :         m_apoHandlers{};
     587             : 
     588             :     VSIFileManager();
     589             : 
     590             :     static VSIFileManager *Get();
     591             : 
     592             :     CPL_DISALLOW_COPY_ASSIGN(VSIFileManager)
     593             : 
     594             :   public:
     595             :     ~VSIFileManager();
     596             : 
     597             :     static VSIFilesystemHandler *GetHandler(const char *);
     598             :     static void InstallHandler(const std::string &osPrefix,
     599             :                                const std::shared_ptr<VSIFilesystemHandler> &);
     600             :     static void InstallHandler(const std::string &osPrefix,
     601             :                                VSIFilesystemHandler *)
     602             :         CPL_WARN_DEPRECATED("Use version with std::shared_ptr<> instead");
     603             :     static void RemoveHandler(const std::string &osPrefix);
     604             : 
     605             :     static char **GetPrefixes();
     606             : };
     607             : #endif /* #ifndef DOXYGEN_SKIP */
     608             : 
     609             : /************************************************************************/
     610             : /* ==================================================================== */
     611             : /*                       VSIArchiveFilesystemHandler                   */
     612             : /* ==================================================================== */
     613             : /************************************************************************/
     614             : 
     615             : #ifndef DOXYGEN_SKIP
     616             : 
     617        1547 : class VSIArchiveEntryFileOffset
     618             : {
     619             :   public:
     620             :     virtual ~VSIArchiveEntryFileOffset();
     621             : };
     622             : 
     623             : class VSIArchiveEntry
     624             : {
     625             :   public:
     626             :     std::string fileName{};
     627             :     vsi_l_offset uncompressed_size = 0;
     628             :     std::unique_ptr<VSIArchiveEntryFileOffset> file_pos{};
     629             :     bool bIsDir = false;
     630             :     GIntBig nModifiedTime = 0;
     631             : };
     632             : 
     633          75 : class VSIArchiveContent
     634             : {
     635             :   public:
     636             :     time_t mTime = 0;
     637             :     vsi_l_offset nFileSize = 0;
     638             :     std::vector<VSIArchiveEntry> entries{};
     639             : 
     640             :     // Store list of child indices for each directory
     641             :     using DirectoryChildren = std::vector<int>;
     642             : 
     643             :     std::map<std::string, DirectoryChildren> dirIndex{};
     644             : 
     645         225 :     VSIArchiveContent() = default;
     646             : 
     647             :     ~VSIArchiveContent();
     648             : 
     649             :   private:
     650             :     CPL_DISALLOW_COPY_ASSIGN(VSIArchiveContent)
     651             : };
     652             : 
     653        5169 : class VSIArchiveReader
     654             : {
     655             :   public:
     656             :     virtual ~VSIArchiveReader();
     657             : 
     658             :     virtual int GotoFirstFile() = 0;
     659             :     virtual int GotoNextFile() = 0;
     660             :     virtual VSIArchiveEntryFileOffset *GetFileOffset() = 0;
     661             :     virtual GUIntBig GetFileSize() = 0;
     662             :     virtual CPLString GetFileName() = 0;
     663             :     virtual GIntBig GetModifiedTime() = 0;
     664             :     virtual int GotoFileOffset(VSIArchiveEntryFileOffset *pOffset) = 0;
     665             : };
     666             : 
     667        5828 : class VSIArchiveFilesystemHandler /* non final */ : public VSIFilesystemHandler
     668             : {
     669             :     CPL_DISALLOW_COPY_ASSIGN(VSIArchiveFilesystemHandler)
     670             : 
     671             :     bool FindFileInArchive(const char *archiveFilename,
     672             :                            const char *fileInArchiveName,
     673             :                            const VSIArchiveEntry **archiveEntry);
     674             : 
     675             :   protected:
     676             :     mutable std::recursive_mutex oMutex{};
     677             : 
     678             :     /* We use a cache that contains the list of files contained in a VSIArchive
     679             :      * file as */
     680             :     /* unarchive.c is quite inefficient in listing them. This speeds up access
     681             :      * to VSIArchive files */
     682             :     /* containing ~1000 files like a CADRG product */
     683             :     std::map<CPLString, std::unique_ptr<VSIArchiveContent>> oFileList{};
     684             : 
     685             :     virtual const char *GetPrefix() const = 0;
     686             :     virtual std::vector<CPLString> GetExtensions() const = 0;
     687             :     virtual std::unique_ptr<VSIArchiveReader>
     688             :     CreateReader(const char *pszArchiveFileName) = 0;
     689             : 
     690             :   public:
     691             :     VSIArchiveFilesystemHandler();
     692             :     ~VSIArchiveFilesystemHandler() override;
     693             : 
     694             :     int Stat(const char *pszFilename, VSIStatBufL *pStatBuf,
     695             :              int nFlags) override;
     696             :     char **ReadDirEx(const char *pszDirname, int nMaxFiles) override;
     697             : 
     698             :     virtual const VSIArchiveContent *
     699             :     GetContentOfArchive(const char *archiveFilename,
     700             :                         VSIArchiveReader *poReader = nullptr);
     701             :     virtual char *SplitFilename(const char *pszFilename,
     702             :                                 CPLString &osFileInArchive,
     703             :                                 bool bCheckMainFileExists,
     704             :                                 bool bSetError) const;
     705             :     virtual std::unique_ptr<VSIArchiveReader>
     706             :     OpenArchiveFile(const char *archiveFilename, const char *fileInArchiveName);
     707             : 
     708             :     bool IsLocal(const char *pszPath) const override;
     709             : 
     710             :     bool IsArchive(const char *pszPath) const override;
     711             : 
     712           0 :     bool SupportsSequentialWrite(const char * /* pszPath */,
     713             :                                  bool /* bAllowLocalTempFile */) override
     714             :     {
     715           0 :         return false;
     716             :     }
     717             : 
     718           0 :     bool SupportsRandomWrite(const char * /* pszPath */,
     719             :                              bool /* bAllowLocalTempFile */) override
     720             :     {
     721           0 :         return false;
     722             :     }
     723             : };
     724             : 
     725             : /************************************************************************/
     726             : /*                                VSIDIR                                */
     727             : /************************************************************************/
     728             : 
     729             : struct CPL_DLL VSIDIR
     730             : {
     731        3627 :     VSIDIR() = default;
     732             :     virtual ~VSIDIR();
     733             : 
     734             :     virtual const VSIDIREntry *NextDirEntry() = 0;
     735             : 
     736             :   private:
     737             :     VSIDIR(const VSIDIR &) = delete;
     738             :     VSIDIR &operator=(const VSIDIR &) = delete;
     739             : };
     740             : 
     741             : #endif /* #ifndef DOXYGEN_SKIP */
     742             : 
     743             : VSIVirtualHandle CPL_DLL *
     744             : VSICreateBufferedReaderHandle(VSIVirtualHandle *poBaseHandle);
     745             : VSIVirtualHandle *
     746             : VSICreateBufferedReaderHandle(VSIVirtualHandle *poBaseHandle,
     747             :                               const GByte *pabyBeginningContent,
     748             :                               vsi_l_offset nCheatFileSize);
     749             : constexpr int VSI_CACHED_DEFAULT_CHUNK_SIZE = 32768;
     750             : VSIVirtualHandle CPL_DLL *
     751             : VSICreateCachedFile(VSIVirtualHandle *poBaseHandle,
     752             :                     size_t nChunkSize = VSI_CACHED_DEFAULT_CHUNK_SIZE,
     753             :                     size_t nCacheSize = 0);
     754             : 
     755             : const int CPL_DEFLATE_TYPE_GZIP = 0;
     756             : const int CPL_DEFLATE_TYPE_ZLIB = 1;
     757             : const int CPL_DEFLATE_TYPE_RAW_DEFLATE = 2;
     758             : VSIVirtualHandle CPL_DLL *VSICreateGZipWritable(VSIVirtualHandle *poBaseHandle,
     759             :                                                 int nDeflateType,
     760             :                                                 int bAutoCloseBaseHandle);
     761             : 
     762             : VSIVirtualHandle *VSICreateGZipWritable(VSIVirtualHandle *poBaseHandle,
     763             :                                         int nDeflateType,
     764             :                                         bool bAutoCloseBaseHandle, int nThreads,
     765             :                                         size_t nChunkSize,
     766             :                                         size_t nSOZIPIndexEltSize,
     767             :                                         std::vector<uint8_t> *panSOZIPIndex);
     768             : 
     769             : VSIVirtualHandle *
     770             : VSICreateUploadOnCloseFile(VSIVirtualHandleUniquePtr &&poWritableHandle,
     771             :                            VSIVirtualHandleUniquePtr &&poTmpFile,
     772             :                            const std::string &osTmpFilename);
     773             : 
     774             : #endif /* ndef CPL_VSI_VIRTUAL_H_INCLUDED */

Generated by: LCOV version 1.14