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 48638 : inline int Seek(int &&nOffset, int nWhence)
55 : {
56 48638 : 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 : 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 98 : virtual void AdviseRead(CPL_UNUSED int nRanges,
108 : CPL_UNUSED const vsi_l_offset *panOffsets,
109 : CPL_UNUSED const size_t *panSizes)
110 : {
111 98 : }
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 226 : virtual size_t GetAdviseReadTotalBytesLimit() const
126 : {
127 226 : 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 48792 : virtual int Flush()
143 : {
144 48792 : 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 8 : virtual void Interrupt()
171 : {
172 8 : }
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 373490 : virtual ~VSIVirtualHandle()
185 373490 : {
186 373490 : }
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 56063 : void operator()(VSIVirtualHandle *poHandle)
200 : {
201 56063 : if (poHandle)
202 : {
203 56006 : poHandle->Close();
204 55893 : delete poHandle;
205 : }
206 55914 : }
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 32773 : 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 4 : virtual char **ReadDirEx(const char * /*pszDirname*/, int /* nMaxFiles */)
388 : {
389 4 : return nullptr;
390 : }
391 :
392 82513 : virtual char **SiblingFiles(const char * /*pszFilename*/)
393 : {
394 82513 : 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 29974 : virtual int IsCaseSensitive(const char *pszFilename)
409 : {
410 : (void)pszFilename;
411 29974 : 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 15644 : virtual int HasOptimizedReadMultiRange(const char * /* pszPath */)
425 : {
426 15644 : 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 33194 : GetStreamingFilename(const std::string &osFilename) const
505 : {
506 33194 : return osFilename;
507 : }
508 :
509 : virtual std::string
510 1609 : GetNonStreamingFilename(const std::string &osFilename) const
511 : {
512 1609 : 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 114 : GetCanonicalFilename(const std::string &osFilename) const
524 : {
525 114 : return osFilename;
526 : }
527 :
528 2245 : virtual bool IsLocal(const char * /* pszPath */) const
529 : {
530 2245 : 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 956959 : virtual const char *GetDirectorySeparator(CPL_UNUSED const char *pszPath)
570 : {
571 956959 : return "/";
572 : }
573 :
574 : /** Returns a hint about the path that this file system
575 : * could (potentially) recognize given the input path.
576 : *
577 : * e.g. /vsizip/ will return "/vsizip/my.zip" if provided with "my.zip",
578 : * /vsicurl/ will return "/vsicurl/https://example.com" if provided with
579 : * "https://example.com", /vsis3/ will return "/vsis3/bucket/object" if
580 : * provided with "s3://bucket/object", etc.
581 : *
582 : * Returns an empty string if the input path cannot easily be identified
583 : * as a potential match for the file system.
584 : */
585 : virtual std::string
586 143444 : GetHintForPotentiallyRecognizedPath(const std::string &osPath)
587 : {
588 : (void)osPath;
589 143444 : return std::string();
590 : }
591 : };
592 : #endif /* #ifndef DOXYGEN_SKIP */
593 :
594 : /************************************************************************/
595 : /* VSIFileManager */
596 : /************************************************************************/
597 :
598 : #ifndef DOXYGEN_SKIP
599 2923 : class CPL_DLL VSIFileManager
600 : {
601 : private:
602 : std::shared_ptr<VSIFilesystemHandler> m_poDefaultHandler{};
603 : std::map<std::string, std::shared_ptr<VSIFilesystemHandler>>
604 : m_apoHandlers{};
605 :
606 : VSIFileManager();
607 :
608 : static VSIFileManager *Get();
609 :
610 : CPL_DISALLOW_COPY_ASSIGN(VSIFileManager)
611 :
612 : public:
613 : ~VSIFileManager();
614 :
615 : static VSIFilesystemHandler *GetHandler(const char *);
616 : static void InstallHandler(const std::string &osPrefix,
617 : const std::shared_ptr<VSIFilesystemHandler> &);
618 : static void InstallHandler(const std::string &osPrefix,
619 : VSIFilesystemHandler *)
620 : CPL_WARN_DEPRECATED("Use version with std::shared_ptr<> instead");
621 : static void RemoveHandler(const std::string &osPrefix);
622 :
623 : static char **GetPrefixes();
624 : };
625 : #endif /* #ifndef DOXYGEN_SKIP */
626 :
627 : /************************************************************************/
628 : /* ==================================================================== */
629 : /* VSIArchiveFilesystemHandler */
630 : /* ==================================================================== */
631 : /************************************************************************/
632 :
633 : #ifndef DOXYGEN_SKIP
634 :
635 1548 : class VSIArchiveEntryFileOffset
636 : {
637 : public:
638 : virtual ~VSIArchiveEntryFileOffset();
639 : };
640 :
641 : class VSIArchiveEntry
642 : {
643 : public:
644 : std::string fileName{};
645 : vsi_l_offset uncompressed_size = 0;
646 : std::unique_ptr<VSIArchiveEntryFileOffset> file_pos{};
647 : bool bIsDir = false;
648 : GIntBig nModifiedTime = 0;
649 : };
650 :
651 75 : class VSIArchiveContent
652 : {
653 : public:
654 : time_t mTime = 0;
655 : vsi_l_offset nFileSize = 0;
656 : std::vector<VSIArchiveEntry> entries{};
657 :
658 : // Store list of child indices for each directory
659 : using DirectoryChildren = std::vector<int>;
660 :
661 : std::map<std::string, DirectoryChildren> dirIndex{};
662 :
663 225 : VSIArchiveContent() = default;
664 :
665 : ~VSIArchiveContent();
666 :
667 : private:
668 : CPL_DISALLOW_COPY_ASSIGN(VSIArchiveContent)
669 : };
670 :
671 5173 : class VSIArchiveReader
672 : {
673 : public:
674 : virtual ~VSIArchiveReader();
675 :
676 : virtual int GotoFirstFile() = 0;
677 : virtual int GotoNextFile() = 0;
678 : virtual VSIArchiveEntryFileOffset *GetFileOffset() = 0;
679 : virtual GUIntBig GetFileSize() = 0;
680 : virtual CPLString GetFileName() = 0;
681 : virtual GIntBig GetModifiedTime() = 0;
682 : virtual int GotoFileOffset(VSIArchiveEntryFileOffset *pOffset) = 0;
683 : };
684 :
685 5846 : class VSIArchiveFilesystemHandler /* non final */ : public VSIFilesystemHandler
686 : {
687 : CPL_DISALLOW_COPY_ASSIGN(VSIArchiveFilesystemHandler)
688 :
689 : bool FindFileInArchive(const char *archiveFilename,
690 : const char *fileInArchiveName,
691 : const VSIArchiveEntry **archiveEntry);
692 :
693 : protected:
694 : mutable std::recursive_mutex oMutex{};
695 :
696 : /* We use a cache that contains the list of files contained in a VSIArchive
697 : * file as */
698 : /* unarchive.c is quite inefficient in listing them. This speeds up access
699 : * to VSIArchive files */
700 : /* containing ~1000 files like a CADRG product */
701 : std::map<CPLString, std::unique_ptr<VSIArchiveContent>> oFileList{};
702 :
703 : virtual const char *GetPrefix() const = 0;
704 : virtual std::vector<CPLString> GetExtensions() const = 0;
705 : virtual std::unique_ptr<VSIArchiveReader>
706 : CreateReader(const char *pszArchiveFileName) = 0;
707 :
708 : public:
709 : VSIArchiveFilesystemHandler();
710 : ~VSIArchiveFilesystemHandler() override;
711 :
712 : int Stat(const char *pszFilename, VSIStatBufL *pStatBuf,
713 : int nFlags) override;
714 : char **ReadDirEx(const char *pszDirname, int nMaxFiles) override;
715 :
716 : virtual const VSIArchiveContent *
717 : GetContentOfArchive(const char *archiveFilename,
718 : VSIArchiveReader *poReader = nullptr);
719 : virtual std::unique_ptr<char, VSIFreeReleaser>
720 : SplitFilename(const char *pszFilename, CPLString &osFileInArchive,
721 : bool bCheckMainFileExists, bool bSetError) const;
722 : virtual std::unique_ptr<VSIArchiveReader>
723 : OpenArchiveFile(const char *archiveFilename, const char *fileInArchiveName);
724 :
725 : bool IsLocal(const char *pszPath) const override;
726 :
727 : bool IsArchive(const char *pszPath) const override;
728 :
729 0 : bool SupportsSequentialWrite(const char * /* pszPath */,
730 : bool /* bAllowLocalTempFile */) override
731 : {
732 0 : return false;
733 : }
734 :
735 0 : bool SupportsRandomWrite(const char * /* pszPath */,
736 : bool /* bAllowLocalTempFile */) override
737 : {
738 0 : return false;
739 : }
740 :
741 : std::string
742 : GetHintForPotentiallyRecognizedPath(const std::string &osPath) override;
743 : };
744 :
745 : /************************************************************************/
746 : /* VSIDIR */
747 : /************************************************************************/
748 :
749 : struct CPL_DLL VSIDIR
750 : {
751 3778 : VSIDIR() = default;
752 : virtual ~VSIDIR();
753 :
754 : virtual const VSIDIREntry *NextDirEntry() = 0;
755 :
756 : private:
757 : VSIDIR(const VSIDIR &) = delete;
758 : VSIDIR &operator=(const VSIDIR &) = delete;
759 : };
760 :
761 : #endif /* #ifndef DOXYGEN_SKIP */
762 :
763 : VSIVirtualHandle CPL_DLL *
764 : VSICreateBufferedReaderHandle(VSIVirtualHandle *poBaseHandle);
765 : VSIVirtualHandle *
766 : VSICreateBufferedReaderHandle(VSIVirtualHandle *poBaseHandle,
767 : const GByte *pabyBeginningContent,
768 : vsi_l_offset nCheatFileSize);
769 : constexpr int VSI_CACHED_DEFAULT_CHUNK_SIZE = 32768;
770 : VSIVirtualHandle CPL_DLL *
771 : VSICreateCachedFile(VSIVirtualHandle *poBaseHandle,
772 : size_t nChunkSize = VSI_CACHED_DEFAULT_CHUNK_SIZE,
773 : size_t nCacheSize = 0);
774 :
775 : const int CPL_DEFLATE_TYPE_GZIP = 0;
776 : const int CPL_DEFLATE_TYPE_ZLIB = 1;
777 : const int CPL_DEFLATE_TYPE_RAW_DEFLATE = 2;
778 : VSIVirtualHandle CPL_DLL *VSICreateGZipWritable(VSIVirtualHandle *poBaseHandle,
779 : int nDeflateType,
780 : int bAutoCloseBaseHandle);
781 :
782 : VSIVirtualHandle *VSICreateGZipWritable(VSIVirtualHandle *poBaseHandle,
783 : int nDeflateType,
784 : bool bAutoCloseBaseHandle, int nThreads,
785 : size_t nChunkSize,
786 : size_t nSOZIPIndexEltSize,
787 : std::vector<uint8_t> *panSOZIPIndex);
788 :
789 : VSIVirtualHandle *
790 : VSICreateUploadOnCloseFile(VSIVirtualHandleUniquePtr &&poWritableHandle,
791 : VSIVirtualHandleUniquePtr &&poTmpFile,
792 : const std::string &osTmpFilename);
793 :
794 : #endif /* ndef CPL_VSI_VIRTUAL_H_INCLUDED */
|