Coverage Report

Created: 2026-02-14 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/port/cpl_vsi_virtual.h
Line
Count
Source
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
    inline int Seek(int &&nOffset, int nWhence)
55
1.13k
    {
56
1.13k
        return Seek(static_cast<vsi_l_offset>(nOffset), nWhence);
57
1.13k
    }
58
59
    inline int Seek(unsigned &&nOffset, int nWhence)
60
0
    {
61
0
        return Seek(static_cast<vsi_l_offset>(nOffset), nWhence);
62
0
    }
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
    Seek(T nOffset, int nWhence)
69
    {
70
        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
    virtual void AdviseRead(CPL_UNUSED int nRanges,
108
                            CPL_UNUSED const vsi_l_offset *panOffsets,
109
                            CPL_UNUSED const size_t *panSizes)
110
0
    {
111
0
    }
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
    virtual size_t GetAdviseReadTotalBytesLimit() const
126
0
    {
127
0
        return 0;
128
0
    }
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
    virtual int Flush()
143
0
    {
144
0
        return 0;
145
0
    }
146
147
    virtual int Close() = 0;
148
    // Base implementation that only supports file extension.
149
    virtual int Truncate(vsi_l_offset nNewSize);
150
151
    virtual void *GetNativeFileDescriptor()
152
0
    {
153
0
        return nullptr;
154
0
    }
155
156
    virtual VSIRangeStatus GetRangeStatus(CPL_UNUSED vsi_l_offset nOffset,
157
                                          CPL_UNUSED vsi_l_offset nLength)
158
0
    {
159
0
        return VSI_RANGE_STATUS_UNKNOWN;
160
0
    }
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
    virtual void Interrupt()
171
0
    {
172
0
    }
173
174
    /** For a file created with CreateOnlyVisibleAtCloseTime(), ask for the
175
     * file to not be created at all (if possible)
176
     */
177
    virtual void CancelCreation()
178
0
    {
179
0
    }
180
181
    // NOTE: when adding new methods, besides the "actual" implementations,
182
    // also consider the VSICachedFile and VSIVirtualHandleOnlyVisibleAtCloseTime one.
183
184
    virtual ~VSIVirtualHandle()
185
10.0k
    {
186
10.0k
    }
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
    void operator()(VSIVirtualHandle *poHandle)
200
2.42k
    {
201
2.42k
        if (poHandle)
202
2.42k
        {
203
2.42k
            poHandle->Close();
204
2.42k
            delete poHandle;
205
2.42k
        }
206
2.42k
    }
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
    explicit VSIProxyFileHandle(VSIVirtualHandleUniquePtr &&nativeHandle)
225
0
        : m_nativeHandle(std::move(nativeHandle))
226
0
    {
227
0
    }
228
229
    int Seek(vsi_l_offset nOffset, int nWhence) override
230
0
    {
231
0
        return m_nativeHandle->Seek(nOffset, nWhence);
232
0
    }
233
234
    vsi_l_offset Tell() override
235
0
    {
236
0
        return m_nativeHandle->Tell();
237
0
    }
238
239
    size_t Read(void *pBuffer, size_t nBytes) override
240
0
    {
241
0
        return m_nativeHandle->Read(pBuffer, nBytes);
242
0
    }
243
244
    int ReadMultiRange(int nRanges, void **ppData,
245
                       const vsi_l_offset *panOffsets,
246
                       const size_t *panSizes) override
247
0
    {
248
0
        return m_nativeHandle->ReadMultiRange(nRanges, ppData, panOffsets,
249
0
                                              panSizes);
250
0
    }
251
252
    void AdviseRead(int nRanges, const vsi_l_offset *panOffsets,
253
                    const size_t *panSizes) override
254
0
    {
255
0
        return m_nativeHandle->AdviseRead(nRanges, panOffsets, panSizes);
256
0
    }
257
258
    size_t GetAdviseReadTotalBytesLimit() const override
259
0
    {
260
0
        return m_nativeHandle->GetAdviseReadTotalBytesLimit();
261
0
    }
262
263
    size_t Write(const void *pBuffer, size_t nBytes) override
264
0
    {
265
0
        return m_nativeHandle->Write(pBuffer, nBytes);
266
0
    }
267
268
    void ClearErr() override
269
0
    {
270
0
        return m_nativeHandle->ClearErr();
271
0
    }
272
273
    int Eof() override
274
0
    {
275
0
        return m_nativeHandle->Eof();
276
0
    }
277
278
    int Error() override
279
0
    {
280
0
        return m_nativeHandle->Error();
281
0
    }
282
283
    int Flush() override
284
0
    {
285
0
        return m_nativeHandle->Flush();
286
0
    }
287
288
    int Close() override
289
0
    {
290
0
        return m_nativeHandle->Close();
291
0
    }
292
293
    int Truncate(vsi_l_offset nNewSize) override
294
0
    {
295
0
        return m_nativeHandle->Truncate(nNewSize);
296
0
    }
297
298
    void *GetNativeFileDescriptor() override
299
0
    {
300
0
        return m_nativeHandle->GetNativeFileDescriptor();
301
0
    }
302
303
    VSIRangeStatus GetRangeStatus(vsi_l_offset nOffset,
304
                                  vsi_l_offset nLength) override
305
0
    {
306
0
        return m_nativeHandle->GetRangeStatus(nOffset, nLength);
307
0
    }
308
309
    bool HasPRead() const override
310
0
    {
311
0
        return m_nativeHandle->HasPRead();
312
0
    }
313
314
    size_t PRead(void *pBuffer, size_t nSize,
315
                 vsi_l_offset nOffset) const override
316
0
    {
317
0
        return m_nativeHandle->PRead(pBuffer, nSize, nOffset);
318
0
    }
319
320
    void Interrupt() override
321
0
    {
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
0
    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
    virtual int Unlink(const char *pszFilename)
357
0
    {
358
0
        (void)pszFilename;
359
0
        errno = ENOENT;
360
0
        return -1;
361
0
    }
362
363
    virtual int *UnlinkBatch(CSLConstList papszFiles);
364
365
    virtual int Mkdir(const char *pszDirname, long nMode)
366
0
    {
367
0
        (void)pszDirname;
368
0
        (void)nMode;
369
0
        errno = ENOENT;
370
0
        return -1;
371
0
    }
372
373
    virtual int Rmdir(const char *pszDirname)
374
0
    {
375
0
        (void)pszDirname;
376
0
        errno = ENOENT;
377
0
        return -1;
378
0
    }
379
380
    virtual int RmdirRecursive(const char *pszDirname);
381
382
    char **ReadDir(const char *pszDirname)
383
0
    {
384
0
        return ReadDirEx(pszDirname, 0);
385
0
    }
386
387
    virtual char **ReadDirEx(const char * /*pszDirname*/, int /* nMaxFiles */)
388
0
    {
389
0
        return nullptr;
390
0
    }
391
392
    virtual char **SiblingFiles(const char * /*pszFilename*/)
393
0
    {
394
0
        return nullptr;
395
0
    }
396
397
    virtual int Rename(const char *oldpath, const char *newpath,
398
                       GDALProgressFunc pProgressFunc, void *pProgressData)
399
0
    {
400
0
        (void)oldpath;
401
0
        (void)newpath;
402
0
        (void)pProgressFunc;
403
0
        (void)pProgressData;
404
0
        errno = ENOENT;
405
0
        return -1;
406
0
    }
407
408
    virtual int IsCaseSensitive(const char *pszFilename)
409
0
    {
410
0
        (void)pszFilename;
411
0
        return TRUE;
412
0
    }
413
414
    virtual GIntBig GetDiskFreeSpace(const char * /* pszDirname */)
415
0
    {
416
0
        return -1;
417
0
    }
418
419
    virtual int SupportsSparseFiles(const char * /* pszPath */)
420
0
    {
421
0
        return FALSE;
422
0
    }
423
424
    virtual int HasOptimizedReadMultiRange(const char * /* pszPath */)
425
0
    {
426
0
        return FALSE;
427
0
    }
428
429
    virtual const char *GetActualURL(const char * /*pszFilename*/)
430
0
    {
431
0
        return nullptr;
432
0
    }
433
434
    virtual const char *GetOptions()
435
0
    {
436
0
        return nullptr;
437
0
    }
438
439
    virtual char *GetSignedURL(const char * /*pszFilename*/,
440
                               CSLConstList /* papszOptions */)
441
0
    {
442
0
        return nullptr;
443
0
    }
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
    virtual bool AbortPendingUploads(const char * /*pszFilename*/)
499
0
    {
500
0
        return true;
501
0
    }
502
503
    virtual std::string
504
    GetStreamingFilename(const std::string &osFilename) const
505
0
    {
506
0
        return osFilename;
507
0
    }
508
509
    virtual std::string
510
    GetNonStreamingFilename(const std::string &osFilename) const
511
0
    {
512
0
        return osFilename;
513
0
    }
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
    GetCanonicalFilename(const std::string &osFilename) const
524
0
    {
525
0
        return osFilename;
526
0
    }
527
528
    virtual bool IsLocal(const char * /* pszPath */) const
529
0
    {
530
0
        return true;
531
0
    }
532
533
    virtual bool IsArchive(const char * /* pszPath */) const
534
0
    {
535
0
        return false;
536
0
    }
537
538
    virtual bool SupportsSequentialWrite(const char * /* pszPath */,
539
                                         bool /* bAllowLocalTempFile */)
540
0
    {
541
0
        return true;
542
0
    }
543
544
    virtual bool SupportsRandomWrite(const char * /* pszPath */,
545
                                     bool /* bAllowLocalTempFile */)
546
0
    {
547
0
        return true;
548
0
    }
549
550
    virtual bool SupportsRead(const char * /* pszPath */)
551
0
    {
552
0
        return true;
553
0
    }
554
555
    virtual VSIFilesystemHandler *Duplicate(const char * /* pszPrefix */)
556
0
    {
557
0
        CPLError(CE_Failure, CPLE_NotSupported,
558
0
                 "Duplicate() not supported on this file "
559
0
                 "system");
560
0
        return nullptr;
561
0
    }
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
    virtual const char *GetDirectorySeparator(CPL_UNUSED const char *pszPath)
570
14.8k
    {
571
14.8k
        return "/";
572
14.8k
    }
573
};
574
#endif /* #ifndef DOXYGEN_SKIP */
575
576
/************************************************************************/
577
/*                            VSIFileManager                            */
578
/************************************************************************/
579
580
#ifndef DOXYGEN_SKIP
581
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
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
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
0
    VSIArchiveContent() = default;
646
647
    ~VSIArchiveContent();
648
649
  private:
650
    CPL_DISALLOW_COPY_ASSIGN(VSIArchiveContent)
651
};
652
653
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
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 std::unique_ptr<char, VSIFreeReleaser>
702
    SplitFilename(const char *pszFilename, CPLString &osFileInArchive,
703
                  bool bCheckMainFileExists, bool bSetError) const;
704
    virtual std::unique_ptr<VSIArchiveReader>
705
    OpenArchiveFile(const char *archiveFilename, const char *fileInArchiveName);
706
707
    bool IsLocal(const char *pszPath) const override;
708
709
    bool IsArchive(const char *pszPath) const override;
710
711
    bool SupportsSequentialWrite(const char * /* pszPath */,
712
                                 bool /* bAllowLocalTempFile */) override
713
0
    {
714
0
        return false;
715
0
    }
716
717
    bool SupportsRandomWrite(const char * /* pszPath */,
718
                             bool /* bAllowLocalTempFile */) override
719
0
    {
720
0
        return false;
721
0
    }
722
};
723
724
/************************************************************************/
725
/*                                VSIDIR                                */
726
/************************************************************************/
727
728
struct CPL_DLL VSIDIR
729
{
730
0
    VSIDIR() = default;
731
    virtual ~VSIDIR();
732
733
    virtual const VSIDIREntry *NextDirEntry() = 0;
734
735
  private:
736
    VSIDIR(const VSIDIR &) = delete;
737
    VSIDIR &operator=(const VSIDIR &) = delete;
738
};
739
740
#endif /* #ifndef DOXYGEN_SKIP */
741
742
VSIVirtualHandle CPL_DLL *
743
VSICreateBufferedReaderHandle(VSIVirtualHandle *poBaseHandle);
744
VSIVirtualHandle *
745
VSICreateBufferedReaderHandle(VSIVirtualHandle *poBaseHandle,
746
                              const GByte *pabyBeginningContent,
747
                              vsi_l_offset nCheatFileSize);
748
constexpr int VSI_CACHED_DEFAULT_CHUNK_SIZE = 32768;
749
VSIVirtualHandle CPL_DLL *
750
VSICreateCachedFile(VSIVirtualHandle *poBaseHandle,
751
                    size_t nChunkSize = VSI_CACHED_DEFAULT_CHUNK_SIZE,
752
                    size_t nCacheSize = 0);
753
754
const int CPL_DEFLATE_TYPE_GZIP = 0;
755
const int CPL_DEFLATE_TYPE_ZLIB = 1;
756
const int CPL_DEFLATE_TYPE_RAW_DEFLATE = 2;
757
VSIVirtualHandle CPL_DLL *VSICreateGZipWritable(VSIVirtualHandle *poBaseHandle,
758
                                                int nDeflateType,
759
                                                int bAutoCloseBaseHandle);
760
761
VSIVirtualHandle *VSICreateGZipWritable(VSIVirtualHandle *poBaseHandle,
762
                                        int nDeflateType,
763
                                        bool bAutoCloseBaseHandle, int nThreads,
764
                                        size_t nChunkSize,
765
                                        size_t nSOZIPIndexEltSize,
766
                                        std::vector<uint8_t> *panSOZIPIndex);
767
768
VSIVirtualHandle *
769
VSICreateUploadOnCloseFile(VSIVirtualHandleUniquePtr &&poWritableHandle,
770
                           VSIVirtualHandleUniquePtr &&poTmpFile,
771
                           const std::string &osTmpFilename);
772
773
#endif /* ndef CPL_VSI_VIRTUAL_H_INCLUDED */