• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OSGeo / gdal / 16038479760

03 Jul 2025 12:12AM UTC coverage: 71.106% (-0.004%) from 71.11%
16038479760

Pull #12692

github

web-flow
Merge efeee3602 into b5d2a80d4
Pull Request #12692: C/C++/Python band algebra: add gdal.abs(), sqrt(), log(), log10() and pow()

80 of 87 new or added lines in 3 files covered. (91.95%)

8848 existing lines in 54 files now uncovered.

574863 of 808463 relevant lines covered (71.11%)

255001.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.07
/port/cpl_vsi_virtual.h
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
#include "cpl_multiproc.h"
25

26
#include <cstdint>
27
#include <map>
28
#include <memory>
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
    virtual vsi_l_offset Tell() = 0;
52
    virtual size_t Read(void *pBuffer, size_t nSize, size_t nCount) = 0;
53
    virtual int ReadMultiRange(int nRanges, void **ppData,
54
                               const vsi_l_offset *panOffsets,
55
                               const size_t *panSizes);
56

57
    /** This method is called when code plans to access soon one or several
58
     * ranges in a file. Some file systems may be able to use this hint to
59
     * for example asynchronously start such requests.
60
     *
61
     * Offsets may be given in a non-increasing order, and may potentially
62
     * overlap.
63
     *
64
     * @param nRanges Size of the panOffsets and panSizes arrays.
65
     * @param panOffsets Array containing the start offset of each range.
66
     * @param panSizes Array containing the size (in bytes) of each range.
67
     * @since GDAL 3.7
68
     */
69
    virtual void AdviseRead(CPL_UNUSED int nRanges,
91✔
70
                            CPL_UNUSED const vsi_l_offset *panOffsets,
71
                            CPL_UNUSED const size_t *panSizes)
72
    {
73
    }
91✔
74

75
    /** Return the total maximum number of bytes that AdviseRead() can handle
76
     * at once.
77
     *
78
     * Some AdviseRead() implementations may give up if the sum of the values
79
     * in the panSizes[] array provided to AdviseRead() exceeds a limit.
80
     *
81
     * Callers might use that threshold to optimize the efficiency of
82
     * AdviseRead().
83
     *
84
     * A returned value of 0 indicates a unknown limit.
85
     * @since GDAL 3.9
86
     */
87
    virtual size_t GetAdviseReadTotalBytesLimit() const
219✔
88
    {
89
        return 0;
219✔
90
    }
91

92
    virtual size_t Write(const void *pBuffer, size_t nSize, size_t nCount) = 0;
93

94
    int Printf(CPL_FORMAT_STRING(const char *pszFormat), ...)
95
        CPL_PRINT_FUNC_FORMAT(2, 3);
96

97
    virtual void ClearErr() = 0;
98

99
    virtual int Eof() = 0;
100

101
    virtual int Error() = 0;
102

103
    virtual int Flush()
35,396✔
104
    {
105
        return 0;
35,396✔
106
    }
107

108
    virtual int Close() = 0;
109
    // Base implementation that only supports file extension.
110
    virtual int Truncate(vsi_l_offset nNewSize);
111

112
    virtual void *GetNativeFileDescriptor()
9✔
113
    {
114
        return nullptr;
9✔
115
    }
116

117
    virtual VSIRangeStatus GetRangeStatus(CPL_UNUSED vsi_l_offset nOffset,
151✔
118
                                          CPL_UNUSED vsi_l_offset nLength)
119
    {
120
        return VSI_RANGE_STATUS_UNKNOWN;
151✔
121
    }
122

123
    virtual bool HasPRead() const;
124
    virtual size_t PRead(void *pBuffer, size_t nSize,
125
                         vsi_l_offset nOffset) const;
126

127
    /** Ask current operations to be interrupted.
128
     * Implementations must be thread-safe, as this will typically be called
129
     * from another thread than the active one for this file.
130
     */
UNCOV
131
    virtual void Interrupt()
×
132
    {
UNCOV
133
    }
×
134

135
    // NOTE: when adding new methods, besides the "actual" implementations,
136
    // also consider the VSICachedFile one.
137

138
    virtual ~VSIVirtualHandle()
316,492✔
139
    {
316,492✔
140
    }
316,492✔
141
};
142

143
/************************************************************************/
144
/*                        VSIVirtualHandleCloser                        */
145
/************************************************************************/
146

147
/** Helper close to use with a std:unique_ptr<VSIVirtualHandle>,
148
 *  such as VSIVirtualHandleUniquePtr. */
149
struct VSIVirtualHandleCloser
150
{
151
    /** Operator () that closes and deletes the file handle. */
152
    void operator()(VSIVirtualHandle *poHandle)
5,947✔
153
    {
154
        if (poHandle)
5,947✔
155
        {
156
            poHandle->Close();
5,929✔
157
            delete poHandle;
5,929✔
158
        }
159
    }
5,947✔
160
};
161

162
/** Unique pointer of VSIVirtualHandle that calls the Close() method */
163
typedef std::unique_ptr<VSIVirtualHandle, VSIVirtualHandleCloser>
164
    VSIVirtualHandleUniquePtr;
165

166
/************************************************************************/
167
/*                         VSIFilesystemHandler                         */
168
/************************************************************************/
169

170
#ifndef DOXYGEN_SKIP
171
class CPL_DLL VSIFilesystemHandler
172
{
173

174
  public:
175
    virtual ~VSIFilesystemHandler()
32,279✔
176
    {
32,279✔
177
    }
32,279✔
178

179
    VSIVirtualHandle *Open(const char *pszFilename, const char *pszAccess);
180

181
    virtual VSIVirtualHandle *Open(const char *pszFilename,
182
                                   const char *pszAccess, bool bSetError,
183
                                   CSLConstList papszOptions) = 0;
184
    virtual int Stat(const char *pszFilename, VSIStatBufL *pStatBuf,
185
                     int nFlags) = 0;
186

187
    virtual int Unlink(const char *pszFilename)
2✔
188
    {
189
        (void)pszFilename;
190
        errno = ENOENT;
2✔
191
        return -1;
2✔
192
    }
193

194
    virtual int *UnlinkBatch(CSLConstList papszFiles);
195

196
    virtual int Mkdir(const char *pszDirname, long nMode)
×
197
    {
198
        (void)pszDirname;
199
        (void)nMode;
200
        errno = ENOENT;
×
201
        return -1;
×
202
    }
203

204
    virtual int Rmdir(const char *pszDirname)
×
205
    {
206
        (void)pszDirname;
207
        errno = ENOENT;
×
208
        return -1;
×
209
    }
210

211
    virtual int RmdirRecursive(const char *pszDirname);
212

213
    char **ReadDir(const char *pszDirname)
5✔
214
    {
215
        return ReadDirEx(pszDirname, 0);
5✔
216
    }
217

218
    virtual char **ReadDirEx(const char * /*pszDirname*/, int /* nMaxFiles */)
3✔
219
    {
220
        return nullptr;
3✔
221
    }
222

223
    virtual char **SiblingFiles(const char * /*pszFilename*/)
76,027✔
224
    {
225
        return nullptr;
76,027✔
226
    }
227

228
    virtual int Rename(const char *oldpath, const char *newpath,
×
229
                       GDALProgressFunc pProgressFunc, void *pProgressData)
230
    {
231
        (void)oldpath;
232
        (void)newpath;
233
        (void)pProgressFunc;
234
        (void)pProgressData;
235
        errno = ENOENT;
×
236
        return -1;
×
237
    }
238

239
    virtual int IsCaseSensitive(const char *pszFilename)
27,782✔
240
    {
241
        (void)pszFilename;
242
        return TRUE;
27,782✔
243
    }
244

245
    virtual GIntBig GetDiskFreeSpace(const char * /* pszDirname */)
×
246
    {
247
        return -1;
×
248
    }
249

250
    virtual int SupportsSparseFiles(const char * /* pszPath */)
×
251
    {
252
        return FALSE;
×
253
    }
254

255
    virtual int HasOptimizedReadMultiRange(const char * /* pszPath */)
15,250✔
256
    {
257
        return FALSE;
15,250✔
258
    }
259

260
    virtual const char *GetActualURL(const char * /*pszFilename*/)
1✔
261
    {
262
        return nullptr;
1✔
263
    }
264

265
    virtual const char *GetOptions()
14✔
266
    {
267
        return nullptr;
14✔
268
    }
269

270
    virtual char *GetSignedURL(const char * /*pszFilename*/,
1✔
271
                               CSLConstList /* papszOptions */)
272
    {
273
        return nullptr;
1✔
274
    }
275

276
    virtual bool Sync(const char *pszSource, const char *pszTarget,
277
                      const char *const *papszOptions,
278
                      GDALProgressFunc pProgressFunc, void *pProgressData,
279
                      char ***ppapszOutputs);
280

281
    virtual int CopyFile(const char *pszSource, const char *pszTarget,
282
                         VSILFILE *fpSource, vsi_l_offset nSourceSize,
283
                         const char *const *papszOptions,
284
                         GDALProgressFunc pProgressFunc, void *pProgressData);
285

286
    virtual int
287
    CopyFileRestartable(const char *pszSource, const char *pszTarget,
288
                        const char *pszInputPayload, char **ppszOutputPayload,
289
                        CSLConstList papszOptions,
290
                        GDALProgressFunc pProgressFunc, void *pProgressData);
291

292
    virtual VSIDIR *OpenDir(const char *pszPath, int nRecurseDepth,
293
                            const char *const *papszOptions);
294

295
    virtual char **GetFileMetadata(const char *pszFilename,
296
                                   const char *pszDomain,
297
                                   CSLConstList papszOptions);
298

299
    virtual bool SetFileMetadata(const char *pszFilename,
300
                                 CSLConstList papszMetadata,
301
                                 const char *pszDomain,
302
                                 CSLConstList papszOptions);
303

304
    virtual bool
305
    MultipartUploadGetCapabilities(int *pbNonSequentialUploadSupported,
306
                                   int *pbParallelUploadSupported,
307
                                   int *pbAbortSupported, size_t *pnMinPartSize,
308
                                   size_t *pnMaxPartSize, int *pnMaxPartCount);
309

310
    virtual char *MultipartUploadStart(const char *pszFilename,
311
                                       CSLConstList papszOptions);
312

313
    virtual char *MultipartUploadAddPart(const char *pszFilename,
314
                                         const char *pszUploadId,
315
                                         int nPartNumber,
316
                                         vsi_l_offset nFileOffset,
317
                                         const void *pData, size_t nDataLength,
318
                                         CSLConstList papszOptions);
319

320
    virtual bool
321
    MultipartUploadEnd(const char *pszFilename, const char *pszUploadId,
322
                       size_t nPartIdsCount, const char *const *apszPartIds,
323
                       vsi_l_offset nTotalSize, CSLConstList papszOptions);
324

325
    virtual bool MultipartUploadAbort(const char *pszFilename,
326
                                      const char *pszUploadId,
327
                                      CSLConstList papszOptions);
328

329
    virtual bool AbortPendingUploads(const char * /*pszFilename*/)
×
330
    {
331
        return true;
×
332
    }
333

334
    virtual std::string
335
    GetStreamingFilename(const std::string &osFilename) const
26,714✔
336
    {
337
        return osFilename;
26,714✔
338
    }
339

340
    virtual std::string
341
    GetNonStreamingFilename(const std::string &osFilename) const
1,421✔
342
    {
343
        return osFilename;
1,421✔
344
    }
345

346
    /** Return the canonical filename.
347
     *
348
     * May be implemented by case-insensitive filesystems
349
     * (currently Win32 and MacOSX)
350
     * to return the filename with its actual case (i.e. the one that would
351
     * be used when listing the content of the directory).
352
     */
353
    virtual std::string
354
    GetCanonicalFilename(const std::string &osFilename) const
248✔
355
    {
356
        return osFilename;
248✔
357
    }
358

359
    virtual bool IsLocal(const char * /* pszPath */)
104✔
360
    {
361
        return true;
104✔
362
    }
363

364
    virtual bool SupportsSequentialWrite(const char * /* pszPath */,
45✔
365
                                         bool /* bAllowLocalTempFile */)
366
    {
367
        return true;
45✔
368
    }
369

370
    virtual bool SupportsRandomWrite(const char * /* pszPath */,
294✔
371
                                     bool /* bAllowLocalTempFile */)
372
    {
373
        return true;
294✔
374
    }
375

376
    virtual bool SupportsRead(const char * /* pszPath */)
43✔
377
    {
378
        return true;
43✔
379
    }
380

381
    virtual VSIFilesystemHandler *Duplicate(const char * /* pszPrefix */)
2✔
382
    {
383
        CPLError(CE_Failure, CPLE_NotSupported,
2✔
384
                 "Duplicate() not supported on this file system");
385
        return nullptr;
2✔
386
    }
387

388
    /** Return the directory separator.
389
     *
390
     * Default is forward slash. The only exception currently is the Windows
391
     * file system which returns anti-slash, unless the specified path is of the
392
     * form "{drive_letter}:/{rest_of_the_path}".
393
     */
394
    virtual const char *GetDirectorySeparator(CPL_UNUSED const char *pszPath)
914,177✔
395
    {
396
        return "/";
914,177✔
397
    }
398
};
399
#endif /* #ifndef DOXYGEN_SKIP */
400

401
/************************************************************************/
402
/*                            VSIFileManager                            */
403
/************************************************************************/
404

405
#ifndef DOXYGEN_SKIP
406
class CPL_DLL VSIFileManager
407
{
408
  private:
409
    VSIFilesystemHandler *poDefaultHandler = nullptr;
410
    std::map<std::string, VSIFilesystemHandler *> oHandlers{};
411

412
    VSIFileManager();
413

414
    static VSIFileManager *Get();
415

416
    CPL_DISALLOW_COPY_ASSIGN(VSIFileManager)
417

418
  public:
419
    ~VSIFileManager();
420

421
    static VSIFilesystemHandler *GetHandler(const char *);
422
    static void InstallHandler(const std::string &osPrefix,
423
                               VSIFilesystemHandler *);
424
    static void RemoveHandler(const std::string &osPrefix);
425

426
    static char **GetPrefixes();
427
};
428
#endif /* #ifndef DOXYGEN_SKIP */
429

430
/************************************************************************/
431
/* ==================================================================== */
432
/*                       VSIArchiveFilesystemHandler                   */
433
/* ==================================================================== */
434
/************************************************************************/
435

436
#ifndef DOXYGEN_SKIP
437

438
class VSIArchiveEntryFileOffset
439
{
440
  public:
441
    virtual ~VSIArchiveEntryFileOffset();
442
};
443

444
typedef struct
445
{
446
    char *fileName;
447
    vsi_l_offset uncompressed_size;
448
    VSIArchiveEntryFileOffset *file_pos;
449
    int bIsDir;
450
    GIntBig nModifiedTime;
451
} VSIArchiveEntry;
452

453
class VSIArchiveContent
454
{
455
  public:
456
    time_t mTime = 0;
457
    vsi_l_offset nFileSize = 0;
458
    int nEntries = 0;
459
    VSIArchiveEntry *entries = nullptr;
460

461
    ~VSIArchiveContent();
462
};
463

464
class VSIArchiveReader
465
{
466
  public:
467
    virtual ~VSIArchiveReader();
468

469
    virtual int GotoFirstFile() = 0;
470
    virtual int GotoNextFile() = 0;
471
    virtual VSIArchiveEntryFileOffset *GetFileOffset() = 0;
472
    virtual GUIntBig GetFileSize() = 0;
473
    virtual CPLString GetFileName() = 0;
474
    virtual GIntBig GetModifiedTime() = 0;
475
    virtual int GotoFileOffset(VSIArchiveEntryFileOffset *pOffset) = 0;
476
};
477

478
class VSIArchiveFilesystemHandler : public VSIFilesystemHandler
479
{
480
    CPL_DISALLOW_COPY_ASSIGN(VSIArchiveFilesystemHandler)
481

482
  protected:
483
    CPLMutex *hMutex = nullptr;
484
    /* We use a cache that contains the list of files contained in a VSIArchive
485
     * file as */
486
    /* unarchive.c is quite inefficient in listing them. This speeds up access
487
     * to VSIArchive files */
488
    /* containing ~1000 files like a CADRG product */
489
    std::map<CPLString, VSIArchiveContent *> oFileList{};
490

491
    virtual const char *GetPrefix() = 0;
492
    virtual std::vector<CPLString> GetExtensions() = 0;
493
    virtual VSIArchiveReader *CreateReader(const char *pszArchiveFileName) = 0;
494

495
  public:
496
    VSIArchiveFilesystemHandler();
497
    virtual ~VSIArchiveFilesystemHandler();
498

499
    int Stat(const char *pszFilename, VSIStatBufL *pStatBuf,
500
             int nFlags) override;
501
    char **ReadDirEx(const char *pszDirname, int nMaxFiles) override;
502

503
    virtual const VSIArchiveContent *
504
    GetContentOfArchive(const char *archiveFilename,
505
                        VSIArchiveReader *poReader = nullptr);
506
    virtual char *SplitFilename(const char *pszFilename,
507
                                CPLString &osFileInArchive,
508
                                bool bCheckMainFileExists, bool bSetError);
509
    virtual VSIArchiveReader *OpenArchiveFile(const char *archiveFilename,
510
                                              const char *fileInArchiveName);
511
    virtual int FindFileInArchive(const char *archiveFilename,
512
                                  const char *fileInArchiveName,
513
                                  const VSIArchiveEntry **archiveEntry);
514

515
    virtual bool IsLocal(const char *pszPath) override;
516

517
    virtual bool
518
    SupportsSequentialWrite(const char * /* pszPath */,
×
519
                            bool /* bAllowLocalTempFile */) override
520
    {
521
        return false;
×
522
    }
523

524
    virtual bool SupportsRandomWrite(const char * /* pszPath */,
×
525
                                     bool /* bAllowLocalTempFile */) override
526
    {
527
        return false;
×
528
    }
529
};
530

531
/************************************************************************/
532
/*                              VSIDIR                                  */
533
/************************************************************************/
534

535
struct CPL_DLL VSIDIR
536
{
537
    VSIDIR() = default;
3,260✔
538
    virtual ~VSIDIR();
539

540
    virtual const VSIDIREntry *NextDirEntry() = 0;
541

542
  private:
543
    VSIDIR(const VSIDIR &) = delete;
544
    VSIDIR &operator=(const VSIDIR &) = delete;
545
};
546

547
#endif /* #ifndef DOXYGEN_SKIP */
548

549
VSIVirtualHandle CPL_DLL *
550
VSICreateBufferedReaderHandle(VSIVirtualHandle *poBaseHandle);
551
VSIVirtualHandle *
552
VSICreateBufferedReaderHandle(VSIVirtualHandle *poBaseHandle,
553
                              const GByte *pabyBeginningContent,
554
                              vsi_l_offset nCheatFileSize);
555
constexpr int VSI_CACHED_DEFAULT_CHUNK_SIZE = 32768;
556
VSIVirtualHandle CPL_DLL *
557
VSICreateCachedFile(VSIVirtualHandle *poBaseHandle,
558
                    size_t nChunkSize = VSI_CACHED_DEFAULT_CHUNK_SIZE,
559
                    size_t nCacheSize = 0);
560

561
const int CPL_DEFLATE_TYPE_GZIP = 0;
562
const int CPL_DEFLATE_TYPE_ZLIB = 1;
563
const int CPL_DEFLATE_TYPE_RAW_DEFLATE = 2;
564
VSIVirtualHandle CPL_DLL *VSICreateGZipWritable(VSIVirtualHandle *poBaseHandle,
565
                                                int nDeflateType,
566
                                                int bAutoCloseBaseHandle);
567

568
VSIVirtualHandle *VSICreateGZipWritable(VSIVirtualHandle *poBaseHandle,
569
                                        int nDeflateType,
570
                                        bool bAutoCloseBaseHandle, int nThreads,
571
                                        size_t nChunkSize,
572
                                        size_t nSOZIPIndexEltSize,
573
                                        std::vector<uint8_t> *panSOZIPIndex);
574

575
VSIVirtualHandle *
576
VSICreateUploadOnCloseFile(VSIVirtualHandleUniquePtr &&poWritableHandle,
577
                           VSIVirtualHandleUniquePtr &&poTmpFile,
578
                           const std::string &osTmpFilename);
579

580
#endif /* ndef CPL_VSI_VIRTUAL_H_INCLUDED */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc