LCOV - code coverage report
Current view: top level - gcore - gdal_priv.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 307 325 94.5 %
Date: 2024-05-04 12:52:34 Functions: 153 167 91.6 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * $Id$
       3             :  *
       4             :  * Name:     gdal_priv.h
       5             :  * Project:  GDAL Core
       6             :  * Purpose:  GDAL Core C++/Private declarations.
       7             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       8             :  *
       9             :  ******************************************************************************
      10             :  * Copyright (c) 1998, Frank Warmerdam
      11             :  * Copyright (c) 2007-2014, Even Rouault <even dot rouault at spatialys.com>
      12             :  *
      13             :  * Permission is hereby granted, free of charge, to any person obtaining a
      14             :  * copy of this software and associated documentation files (the "Software"),
      15             :  * to deal in the Software without restriction, including without limitation
      16             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      17             :  * and/or sell copies of the Software, and to permit persons to whom the
      18             :  * Software is furnished to do so, subject to the following conditions:
      19             :  *
      20             :  * The above copyright notice and this permission notice shall be included
      21             :  * in all copies or substantial portions of the Software.
      22             :  *
      23             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      24             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      26             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      28             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      29             :  * DEALINGS IN THE SOFTWARE.
      30             :  ****************************************************************************/
      31             : 
      32             : #ifndef GDAL_PRIV_H_INCLUDED
      33             : #define GDAL_PRIV_H_INCLUDED
      34             : 
      35             : /**
      36             :  * \file gdal_priv.h
      37             :  *
      38             :  * C++ GDAL entry points.
      39             :  */
      40             : 
      41             : /* -------------------------------------------------------------------- */
      42             : /*      Predeclare various classes before pulling in gdal.h, the        */
      43             : /*      public declarations.                                            */
      44             : /* -------------------------------------------------------------------- */
      45             : class GDALMajorObject;
      46             : class GDALDataset;
      47             : class GDALRasterBand;
      48             : class GDALDriver;
      49             : class GDALRasterAttributeTable;
      50             : class GDALProxyDataset;
      51             : class GDALProxyRasterBand;
      52             : class GDALAsyncReader;
      53             : class GDALRelationship;
      54             : 
      55             : /* -------------------------------------------------------------------- */
      56             : /*      Pull in the public declarations.  This gets the C apis, and     */
      57             : /*      also various constants.  However, we will still get to          */
      58             : /*      provide the real class definitions for the GDAL classes.        */
      59             : /* -------------------------------------------------------------------- */
      60             : 
      61             : #include "gdal.h"
      62             : #include "gdal_frmts.h"
      63             : #include "gdalsubdatasetinfo.h"
      64             : #include "cpl_vsi.h"
      65             : #include "cpl_conv.h"
      66             : #include "cpl_string.h"
      67             : #include "cpl_minixml.h"
      68             : #include "cpl_multiproc.h"
      69             : #include "cpl_atomic_ops.h"
      70             : 
      71             : #include <stdarg.h>
      72             : 
      73             : #include <cmath>
      74             : #include <cstdint>
      75             : #include <iterator>
      76             : #include <limits>
      77             : #include <map>
      78             : #include <memory>
      79             : #include <set>
      80             : #include <vector>
      81             : 
      82             : #include "ogr_core.h"
      83             : #include "ogr_feature.h"
      84             : 
      85             : //! @cond Doxygen_Suppress
      86             : #define GMO_VALID 0x0001
      87             : #define GMO_IGNORE_UNIMPLEMENTED 0x0002
      88             : #define GMO_SUPPORT_MD 0x0004
      89             : #define GMO_SUPPORT_MDMD 0x0008
      90             : #define GMO_MD_DIRTY 0x0010
      91             : #define GMO_PAM_CLASS 0x0020
      92             : 
      93             : //! @endcond
      94             : 
      95             : /************************************************************************/
      96             : /*                       GDALMultiDomainMetadata                        */
      97             : /************************************************************************/
      98             : 
      99             : //! @cond Doxygen_Suppress
     100     4356300 : class CPL_DLL GDALMultiDomainMetadata
     101             : {
     102             :   private:
     103             :     CPLStringList aosDomainList{};
     104             : 
     105             :     struct Comparator
     106             :     {
     107    26748600 :         bool operator()(const char *a, const char *b) const
     108             :         {
     109    26748600 :             return STRCASECMP(a, b) < 0;
     110             :         }
     111             :     };
     112             : 
     113             :     std::map<const char *, CPLStringList, Comparator> oMetadata{};
     114             : 
     115             :   public:
     116             :     GDALMultiDomainMetadata();
     117             :     ~GDALMultiDomainMetadata();
     118             : 
     119             :     int XMLInit(const CPLXMLNode *psMetadata, int bMerge);
     120             :     CPLXMLNode *Serialize() const;
     121             : 
     122      428175 :     CSLConstList GetDomainList() const
     123             :     {
     124      428175 :         return aosDomainList.List();
     125             :     }
     126             : 
     127             :     char **GetMetadata(const char *pszDomain = "");
     128             :     CPLErr SetMetadata(CSLConstList papszMetadata, const char *pszDomain = "");
     129             :     const char *GetMetadataItem(const char *pszName,
     130             :                                 const char *pszDomain = "");
     131             :     CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
     132             :                            const char *pszDomain = "");
     133             : 
     134             :     void Clear();
     135             : 
     136             :     inline void clear()
     137             :     {
     138             :         Clear();
     139             :     }
     140             : 
     141             :   private:
     142             :     CPL_DISALLOW_COPY_ASSIGN(GDALMultiDomainMetadata)
     143             : };
     144             : 
     145             : //! @endcond
     146             : 
     147             : /* ******************************************************************** */
     148             : /*                           GDALMajorObject                            */
     149             : /*                                                                      */
     150             : /*      Base class providing metadata, description and other            */
     151             : /*      services shared by major objects.                               */
     152             : /* ******************************************************************** */
     153             : 
     154             : /** Object with metadata. */
     155             : class CPL_DLL GDALMajorObject
     156             : {
     157             :   protected:
     158             :     //! @cond Doxygen_Suppress
     159             :     int nFlags;  // GMO_* flags.
     160             :     CPLString sDescription{};
     161             :     GDALMultiDomainMetadata oMDMD{};
     162             : 
     163             :     //! @endcond
     164             : 
     165             :     char **BuildMetadataDomainList(char **papszList, int bCheckNonEmpty,
     166             :                                    ...) CPL_NULL_TERMINATED;
     167             : 
     168             :   public:
     169             :     GDALMajorObject();
     170             :     virtual ~GDALMajorObject();
     171             : 
     172             :     int GetMOFlags() const;
     173             :     void SetMOFlags(int nFlagsIn);
     174             : 
     175             :     virtual const char *GetDescription() const;
     176             :     virtual void SetDescription(const char *);
     177             : 
     178             :     virtual char **GetMetadataDomainList();
     179             : 
     180             :     virtual char **GetMetadata(const char *pszDomain = "");
     181             :     virtual CPLErr SetMetadata(char **papszMetadata,
     182             :                                const char *pszDomain = "");
     183             :     virtual const char *GetMetadataItem(const char *pszName,
     184             :                                         const char *pszDomain = "");
     185             :     virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
     186             :                                    const char *pszDomain = "");
     187             : 
     188             :     /** Convert a GDALMajorObject* to a GDALMajorObjectH.
     189             :      * @since GDAL 2.3
     190             :      */
     191         208 :     static inline GDALMajorObjectH ToHandle(GDALMajorObject *poMajorObject)
     192             :     {
     193         208 :         return static_cast<GDALMajorObjectH>(poMajorObject);
     194             :     }
     195             : 
     196             :     /** Convert a GDALMajorObjectH to a GDALMajorObject*.
     197             :      * @since GDAL 2.3
     198             :      */
     199     1202680 :     static inline GDALMajorObject *FromHandle(GDALMajorObjectH hMajorObject)
     200             :     {
     201     1202680 :         return static_cast<GDALMajorObject *>(hMajorObject);
     202             :     }
     203             : };
     204             : 
     205             : /* ******************************************************************** */
     206             : /*                         GDALDefaultOverviews                         */
     207             : /* ******************************************************************** */
     208             : 
     209             : //! @cond Doxygen_Suppress
     210             : class CPL_DLL GDALDefaultOverviews
     211             : {
     212             :     friend class GDALDataset;
     213             : 
     214             :     GDALDataset *poDS;
     215             :     GDALDataset *poODS;
     216             : 
     217             :     CPLString osOvrFilename{};
     218             : 
     219             :     bool bOvrIsAux;
     220             : 
     221             :     bool bCheckedForMask;
     222             :     bool bOwnMaskDS;
     223             :     GDALDataset *poMaskDS;
     224             : 
     225             :     // For "overview datasets" we record base level info so we can
     226             :     // find our way back to get overview masks.
     227             :     GDALDataset *poBaseDS;
     228             : 
     229             :     // Stuff for deferred initialize/overviewscans.
     230             :     bool bCheckedForOverviews;
     231             :     void OverviewScan();
     232             :     char *pszInitName;
     233             :     bool bInitNameIsOVR;
     234             :     char **papszInitSiblingFiles;
     235             : 
     236             :   public:
     237             :     GDALDefaultOverviews();
     238             :     ~GDALDefaultOverviews();
     239             : 
     240             :     void Initialize(GDALDataset *poDSIn, const char *pszName = nullptr,
     241             :                     char **papszSiblingFiles = nullptr, int bNameIsOVR = FALSE);
     242             : 
     243             :     void TransferSiblingFiles(char **papszSiblingFiles);
     244             : 
     245             :     int IsInitialized();
     246             : 
     247             :     int CloseDependentDatasets();
     248             : 
     249             :     // Overview Related
     250             : 
     251             :     int GetOverviewCount(int nBand);
     252             :     GDALRasterBand *GetOverview(int nBand, int iOverview);
     253             : 
     254             :     CPLErr BuildOverviews(const char *pszBasename, const char *pszResampling,
     255             :                           int nOverviews, const int *panOverviewList,
     256             :                           int nBands, const int *panBandList,
     257             :                           GDALProgressFunc pfnProgress, void *pProgressData,
     258             :                           CSLConstList papszOptions);
     259             : 
     260             :     CPLErr BuildOverviewsSubDataset(const char *pszPhysicalFile,
     261             :                                     const char *pszResampling, int nOverviews,
     262             :                                     const int *panOverviewList, int nBands,
     263             :                                     const int *panBandList,
     264             :                                     GDALProgressFunc pfnProgress,
     265             :                                     void *pProgressData,
     266             :                                     CSLConstList papszOptions);
     267             : 
     268             :     CPLErr BuildOverviewsMask(const char *pszResampling, int nOverviews,
     269             :                               const int *panOverviewList,
     270             :                               GDALProgressFunc pfnProgress, void *pProgressData,
     271             :                               CSLConstList papszOptions);
     272             : 
     273             :     CPLErr CleanOverviews();
     274             : 
     275             :     // Mask Related
     276             : 
     277             :     CPLErr CreateMaskBand(int nFlags, int nBand = -1);
     278             :     GDALRasterBand *GetMaskBand(int nBand);
     279             :     int GetMaskFlags(int nBand);
     280             : 
     281             :     int HaveMaskFile(char **papszSiblings = nullptr,
     282             :                      const char *pszBasename = nullptr);
     283             : 
     284       28327 :     char **GetSiblingFiles()
     285             :     {
     286       28327 :         return papszInitSiblingFiles;
     287             :     }
     288             : 
     289             :   private:
     290             :     CPL_DISALLOW_COPY_ASSIGN(GDALDefaultOverviews)
     291             : };
     292             : 
     293             : //! @endcond
     294             : 
     295             : /* ******************************************************************** */
     296             : /*                             GDALOpenInfo                             */
     297             : /* ******************************************************************** */
     298             : 
     299             : /** Class for dataset open functions. */
     300             : class CPL_DLL GDALOpenInfo
     301             : {
     302             :     bool bHasGotSiblingFiles;
     303             :     char **papszSiblingFiles;
     304             :     int nHeaderBytesTried;
     305             : 
     306             :   public:
     307             :     GDALOpenInfo(const char *pszFile, int nOpenFlagsIn,
     308             :                  const char *const *papszSiblingFiles = nullptr);
     309             :     ~GDALOpenInfo(void);
     310             : 
     311             :     /** Filename */
     312             :     char *pszFilename;
     313             :     /** Open options */
     314             :     char **papszOpenOptions;
     315             : 
     316             :     /** Access flag */
     317             :     GDALAccess eAccess;
     318             :     /** Open flags */
     319             :     int nOpenFlags;
     320             : 
     321             :     /** Whether stat()'ing the file was successful */
     322             :     int bStatOK;
     323             :     /** Whether the file is a directory */
     324             :     int bIsDirectory;
     325             : 
     326             :     /** Pointer to the file */
     327             :     VSILFILE *fpL;
     328             : 
     329             :     /** Number of bytes in pabyHeader */
     330             :     int nHeaderBytes;
     331             :     /** Buffer with first bytes of the file */
     332             :     GByte *pabyHeader;
     333             : 
     334             :     /** Allowed drivers (NULL for all) */
     335             :     const char *const *papszAllowedDrivers;
     336             : 
     337             :     int TryToIngest(int nBytes);
     338             :     char **GetSiblingFiles();
     339             :     char **StealSiblingFiles();
     340             :     bool AreSiblingFilesLoaded() const;
     341             : 
     342             :   private:
     343             :     CPL_DISALLOW_COPY_ASSIGN(GDALOpenInfo)
     344             : };
     345             : 
     346             : /* ******************************************************************** */
     347             : /*                             gdal::GCP                                */
     348             : /* ******************************************************************** */
     349             : 
     350             : namespace gdal
     351             : {
     352             : /** C++ wrapper over the C GDAL_GCP structure.
     353             :  *
     354             :  * It has the same binary layout, and thus a gdal::GCP pointer can be cast as a
     355             :  * GDAL_GCP pointer.
     356             :  *
     357             :  * @since 3.9
     358             :  */
     359             : class CPL_DLL GCP
     360             : {
     361             :   public:
     362             :     explicit GCP(const char *pszId = "", const char *pszInfo = "",
     363             :                  double dfPixel = 0, double dfLine = 0, double dfX = 0,
     364             :                  double dfY = 0, double dfZ = 0);
     365             :     ~GCP();
     366             :     GCP(const GCP &);
     367             :     explicit GCP(const GDAL_GCP &other);
     368             :     GCP &operator=(const GCP &);
     369             :     GCP(GCP &&);
     370             :     GCP &operator=(GCP &&);
     371             : 
     372             :     /** Returns the "id" member. */
     373          84 :     inline const char *Id() const
     374             :     {
     375          84 :         return gcp.pszId;
     376             :     }
     377             : 
     378             :     void SetId(const char *pszId);
     379             : 
     380             :     /** Returns the "info" member. */
     381         150 :     inline const char *Info() const
     382             :     {
     383         150 :         return gcp.pszInfo;
     384             :     }
     385             : 
     386             :     void SetInfo(const char *pszInfo);
     387             : 
     388             :     /** Returns the "pixel" member. */
     389         107 :     inline double Pixel() const
     390             :     {
     391         107 :         return gcp.dfGCPPixel;
     392             :     }
     393             : 
     394             :     /** Returns a reference to the "pixel" member. */
     395        2857 :     inline double &Pixel()
     396             :     {
     397        2857 :         return gcp.dfGCPPixel;
     398             :     }
     399             : 
     400             :     /** Returns the "line" member. */
     401         107 :     inline double Line() const
     402             :     {
     403         107 :         return gcp.dfGCPLine;
     404             :     }
     405             : 
     406             :     /** Returns a reference to the "line" member. */
     407        2857 :     inline double &Line()
     408             :     {
     409        2857 :         return gcp.dfGCPLine;
     410             :     }
     411             : 
     412             :     /** Returns the "X" member. */
     413         107 :     inline double X() const
     414             :     {
     415         107 :         return gcp.dfGCPX;
     416             :     }
     417             : 
     418             :     /** Returns a reference to the "X" member. */
     419        2801 :     inline double &X()
     420             :     {
     421        2801 :         return gcp.dfGCPX;
     422             :     }
     423             : 
     424             :     /** Returns the "Y" member. */
     425         107 :     inline double Y() const
     426             :     {
     427         107 :         return gcp.dfGCPY;
     428             :     }
     429             : 
     430             :     /** Returns a reference to the "Y" member. */
     431        2801 :     inline double &Y()
     432             :     {
     433        2801 :         return gcp.dfGCPY;
     434             :     }
     435             : 
     436             :     /** Returns the "Z" member. */
     437          85 :     inline double Z() const
     438             :     {
     439          85 :         return gcp.dfGCPZ;
     440             :     }
     441             : 
     442             :     /** Returns a reference to the "Z" member. */
     443        2697 :     inline double &Z()
     444             :     {
     445        2697 :         return gcp.dfGCPZ;
     446             :     }
     447             : 
     448             :     /** Casts as a C GDAL_GCP pointer */
     449         220 :     inline const GDAL_GCP *c_ptr() const
     450             :     {
     451         220 :         return &gcp;
     452             :     }
     453             : 
     454             :     static const GDAL_GCP *c_ptr(const std::vector<GCP> &asGCPs);
     455             : 
     456             :     static std::vector<GCP> fromC(const GDAL_GCP *pasGCPList, int nGCPCount);
     457             : 
     458             :   private:
     459             :     GDAL_GCP gcp;
     460             : };
     461             : 
     462             : } /* namespace gdal */
     463             : 
     464             : /* ******************************************************************** */
     465             : /*                             GDALDataset                              */
     466             : /* ******************************************************************** */
     467             : 
     468             : class OGRLayer;
     469             : class OGRGeometry;
     470             : class OGRSpatialReference;
     471             : class OGRStyleTable;
     472             : class swq_select;
     473             : class swq_select_parse_options;
     474             : class GDALGroup;
     475             : 
     476             : //! @cond Doxygen_Suppress
     477             : typedef struct GDALSQLParseInfo GDALSQLParseInfo;
     478             : //! @endcond
     479             : 
     480             : //! @cond Doxygen_Suppress
     481             : #ifdef GDAL_COMPILATION
     482             : #define OPTIONAL_OUTSIDE_GDAL(val)
     483             : #else
     484             : #define OPTIONAL_OUTSIDE_GDAL(val) = val
     485             : #endif
     486             : //! @endcond
     487             : 
     488             : /** A set of associated raster bands, usually from one file. */
     489             : class CPL_DLL GDALDataset : public GDALMajorObject
     490             : {
     491             :     friend GDALDatasetH CPL_STDCALL
     492             :     GDALOpenEx(const char *pszFilename, unsigned int nOpenFlags,
     493             :                const char *const *papszAllowedDrivers,
     494             :                const char *const *papszOpenOptions,
     495             :                const char *const *papszSiblingFiles);
     496             :     friend CPLErr CPL_STDCALL GDALClose(GDALDatasetH hDS);
     497             : 
     498             :     friend class GDALDriver;
     499             :     friend class GDALDefaultOverviews;
     500             :     friend class GDALProxyDataset;
     501             :     friend class GDALDriverManager;
     502             : 
     503             :     CPL_INTERNAL void AddToDatasetOpenList();
     504             : 
     505             :     CPL_INTERNAL void UnregisterFromSharedDataset();
     506             : 
     507             :     CPL_INTERNAL static void ReportErrorV(const char *pszDSName,
     508             :                                           CPLErr eErrClass, CPLErrorNum err_no,
     509             :                                           const char *fmt, va_list args);
     510             : 
     511             :   protected:
     512             :     //! @cond Doxygen_Suppress
     513             :     GDALDriver *poDriver = nullptr;
     514             :     GDALAccess eAccess = GA_ReadOnly;
     515             : 
     516             :     // Stored raster information.
     517             :     int nRasterXSize = 512;
     518             :     int nRasterYSize = 512;
     519             :     int nBands = 0;
     520             :     GDALRasterBand **papoBands = nullptr;
     521             : 
     522             :     static constexpr int OPEN_FLAGS_CLOSED = -1;
     523             :     int nOpenFlags =
     524             :         0;  // set to OPEN_FLAGS_CLOSED after Close() has been called
     525             : 
     526             :     int nRefCount = 1;
     527             :     bool bForceCachedIO = false;
     528             :     bool bShared = false;
     529             :     bool bIsInternal = true;
     530             :     bool bSuppressOnClose = false;
     531             : 
     532             :     mutable std::map<std::string, std::unique_ptr<OGRFieldDomain>>
     533             :         m_oMapFieldDomains{};
     534             : 
     535             :     GDALDataset(void);
     536             :     explicit GDALDataset(int bForceCachedIO);
     537             : 
     538             :     void RasterInitialize(int, int);
     539             :     void SetBand(int, GDALRasterBand *);
     540             :     void SetBand(int nNewBand, std::unique_ptr<GDALRasterBand> poBand);
     541             : 
     542             :     GDALDefaultOverviews oOvManager{};
     543             : 
     544             :     virtual CPLErr IBuildOverviews(const char *, int, const int *, int,
     545             :                                    const int *, GDALProgressFunc, void *,
     546             :                                    CSLConstList papszOptions);
     547             : 
     548             :     virtual CPLErr
     549             :     IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int, GDALDataType,
     550             :               int, int *, GSpacing, GSpacing, GSpacing,
     551             :               GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
     552             : 
     553             :     CPLErr
     554             :     BlockBasedRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
     555             :                        GDALDataType, int, int *, GSpacing, GSpacing, GSpacing,
     556             :                        GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
     557             :     CPLErr BlockBasedFlushCache(bool bAtClosing);
     558             : 
     559             :     CPLErr
     560             :     BandBasedRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
     561             :                       int nYSize, void *pData, int nBufXSize, int nBufYSize,
     562             :                       GDALDataType eBufType, int nBandCount, int *panBandMap,
     563             :                       GSpacing nPixelSpace, GSpacing nLineSpace,
     564             :                       GSpacing nBandSpace,
     565             :                       GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
     566             : 
     567             :     CPLErr
     568             :     RasterIOResampled(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
     569             :                       int nYSize, void *pData, int nBufXSize, int nBufYSize,
     570             :                       GDALDataType eBufType, int nBandCount, int *panBandMap,
     571             :                       GSpacing nPixelSpace, GSpacing nLineSpace,
     572             :                       GSpacing nBandSpace,
     573             :                       GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
     574             : 
     575             :     CPLErr ValidateRasterIOOrAdviseReadParameters(
     576             :         const char *pszCallingFunc, int *pbStopProcessingOnCENone, int nXOff,
     577             :         int nYOff, int nXSize, int nYSize, int nBufXSize, int nBufYSize,
     578             :         int nBandCount, int *panBandMap);
     579             : 
     580             :     CPLErr TryOverviewRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
     581             :                                int nXSize, int nYSize, void *pData,
     582             :                                int nBufXSize, int nBufYSize,
     583             :                                GDALDataType eBufType, int nBandCount,
     584             :                                int *panBandMap, GSpacing nPixelSpace,
     585             :                                GSpacing nLineSpace, GSpacing nBandSpace,
     586             :                                GDALRasterIOExtraArg *psExtraArg, int *pbTried);
     587             : 
     588             :     void ShareLockWithParentDataset(GDALDataset *poParentDataset);
     589             : 
     590             :     //! @endcond
     591             : 
     592             :     void CleanupPostFileClosing();
     593             : 
     594             :     virtual int CloseDependentDatasets();
     595             :     //! @cond Doxygen_Suppress
     596             :     int ValidateLayerCreationOptions(const char *const *papszLCO);
     597             : 
     598             :     char **papszOpenOptions = nullptr;
     599             : 
     600             :     friend class GDALRasterBand;
     601             : 
     602             :     // The below methods related to read write mutex are fragile logic, and
     603             :     // should not be used by out-of-tree code if possible.
     604             :     int EnterReadWrite(GDALRWFlag eRWFlag);
     605             :     void LeaveReadWrite();
     606             :     void InitRWLock();
     607             : 
     608             :     void TemporarilyDropReadWriteLock();
     609             :     void ReacquireReadWriteLock();
     610             : 
     611             :     void DisableReadWriteMutex();
     612             : 
     613             :     int AcquireMutex();
     614             :     void ReleaseMutex();
     615             : 
     616             :     bool IsAllBands(int nBandCount, const int *panBandList) const;
     617             :     //! @endcond
     618             : 
     619             :   public:
     620             :     ~GDALDataset() override;
     621             : 
     622             :     virtual CPLErr Close();
     623             : 
     624             :     int GetRasterXSize() const;
     625             :     int GetRasterYSize() const;
     626             :     int GetRasterCount() const;
     627             :     GDALRasterBand *GetRasterBand(int);
     628             :     const GDALRasterBand *GetRasterBand(int) const;
     629             : 
     630             :     /**
     631             :      * @brief SetQueryLoggerFunc
     632             :      * @param pfnQueryLoggerFuncIn query logger function callback
     633             :      * @param poQueryLoggerArgIn arguments passed to the query logger function
     634             :      * @return true on success
     635             :      */
     636             :     virtual bool SetQueryLoggerFunc(GDALQueryLoggerFunc pfnQueryLoggerFuncIn,
     637             :                                     void *poQueryLoggerArgIn);
     638             : 
     639             :     /** Class returned by GetBands() that act as a container for raster bands.
     640             :      */
     641             :     class CPL_DLL Bands
     642             :     {
     643             :       private:
     644             :         friend class GDALDataset;
     645             :         GDALDataset *m_poSelf;
     646             : 
     647           5 :         CPL_INTERNAL explicit Bands(GDALDataset *poSelf) : m_poSelf(poSelf)
     648             :         {
     649           5 :         }
     650             : 
     651           2 :         class CPL_DLL Iterator
     652             :         {
     653             :             struct Private;
     654             :             std::unique_ptr<Private> m_poPrivate;
     655             : 
     656             :           public:
     657             :             Iterator(GDALDataset *poDS, bool bStart);
     658             :             Iterator(const Iterator &oOther);  // declared but not defined.
     659             :                                                // Needed for gcc 5.4 at least
     660             :             Iterator(Iterator &&oOther) noexcept;  // declared but not defined.
     661             :                 // Needed for gcc 5.4 at least
     662             :             ~Iterator();
     663             :             GDALRasterBand *operator*();
     664             :             Iterator &operator++();
     665             :             bool operator!=(const Iterator &it) const;
     666             :         };
     667             : 
     668             :       public:
     669             :         const Iterator begin() const;
     670             : 
     671             :         const Iterator end() const;
     672             : 
     673             :         size_t size() const;
     674             : 
     675             :         GDALRasterBand *operator[](int iBand);
     676             :         GDALRasterBand *operator[](size_t iBand);
     677             :     };
     678             : 
     679             :     Bands GetBands();
     680             : 
     681             :     virtual CPLErr FlushCache(bool bAtClosing = false);
     682             :     virtual CPLErr DropCache();
     683             : 
     684             :     virtual GIntBig GetEstimatedRAMUsage();
     685             : 
     686             :     virtual const OGRSpatialReference *GetSpatialRef() const;
     687             :     virtual CPLErr SetSpatialRef(const OGRSpatialReference *poSRS);
     688             : 
     689             :     // Compatibility layer
     690             :     const char *GetProjectionRef(void) const;
     691             :     CPLErr SetProjection(const char *pszProjection);
     692             : 
     693             :     virtual CPLErr GetGeoTransform(double *padfTransform);
     694             :     virtual CPLErr SetGeoTransform(double *padfTransform);
     695             : 
     696             :     virtual CPLErr AddBand(GDALDataType eType, char **papszOptions = nullptr);
     697             : 
     698             :     virtual void *GetInternalHandle(const char *pszHandleName);
     699             :     virtual GDALDriver *GetDriver(void);
     700             :     virtual char **GetFileList(void);
     701             : 
     702             :     virtual const char *GetDriverName();
     703             : 
     704             :     virtual const OGRSpatialReference *GetGCPSpatialRef() const;
     705             :     virtual int GetGCPCount();
     706             :     virtual const GDAL_GCP *GetGCPs();
     707             :     virtual CPLErr SetGCPs(int nGCPCount, const GDAL_GCP *pasGCPList,
     708             :                            const OGRSpatialReference *poGCP_SRS);
     709             : 
     710             :     // Compatibility layer
     711             :     const char *GetGCPProjection();
     712             :     CPLErr SetGCPs(int nGCPCount, const GDAL_GCP *pasGCPList,
     713             :                    const char *pszGCPProjection);
     714             : 
     715             :     virtual CPLErr AdviseRead(int nXOff, int nYOff, int nXSize, int nYSize,
     716             :                               int nBufXSize, int nBufYSize, GDALDataType eDT,
     717             :                               int nBandCount, int *panBandList,
     718             :                               char **papszOptions);
     719             : 
     720             :     virtual CPLErr CreateMaskBand(int nFlagsIn);
     721             : 
     722             :     virtual GDALAsyncReader *
     723             :     BeginAsyncReader(int nXOff, int nYOff, int nXSize, int nYSize, void *pBuf,
     724             :                      int nBufXSize, int nBufYSize, GDALDataType eBufType,
     725             :                      int nBandCount, int *panBandMap, int nPixelSpace,
     726             :                      int nLineSpace, int nBandSpace, char **papszOptions);
     727             :     virtual void EndAsyncReader(GDALAsyncReader *);
     728             : 
     729             :     //! @cond Doxygen_Suppress
     730             :     struct RawBinaryLayout
     731             :     {
     732             :         enum class Interleaving
     733             :         {
     734             :             UNKNOWN,
     735             :             BIP,
     736             :             BIL,
     737             :             BSQ
     738             :         };
     739             :         std::string osRawFilename{};
     740             :         Interleaving eInterleaving = Interleaving::UNKNOWN;
     741             :         GDALDataType eDataType = GDT_Unknown;
     742             :         bool bLittleEndianOrder = false;
     743             : 
     744             :         vsi_l_offset nImageOffset = 0;
     745             :         GIntBig nPixelOffset = 0;
     746             :         GIntBig nLineOffset = 0;
     747             :         GIntBig nBandOffset = 0;
     748             :     };
     749             : 
     750             :     virtual bool GetRawBinaryLayout(RawBinaryLayout &);
     751             :     //! @endcond
     752             : 
     753             :     CPLErr RasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
     754             :                     GDALDataType, int, int *, GSpacing, GSpacing, GSpacing,
     755             :                     GDALRasterIOExtraArg *psExtraArg
     756             : #ifndef DOXYGEN_SKIP
     757             :                         OPTIONAL_OUTSIDE_GDAL(nullptr)
     758             : #endif
     759             :                         ) CPL_WARN_UNUSED_RESULT;
     760             : 
     761             :     virtual CPLStringList GetCompressionFormats(int nXOff, int nYOff,
     762             :                                                 int nXSize, int nYSize,
     763             :                                                 int nBandCount,
     764             :                                                 const int *panBandList);
     765             :     virtual CPLErr ReadCompressedData(const char *pszFormat, int nXOff,
     766             :                                       int nYOff, int nXSize, int nYSize,
     767             :                                       int nBands, const int *panBandList,
     768             :                                       void **ppBuffer, size_t *pnBufferSize,
     769             :                                       char **ppszDetailedFormat);
     770             : 
     771             :     int Reference();
     772             :     int Dereference();
     773             :     int ReleaseRef();
     774             : 
     775             :     /** Return access mode.
     776             :      * @return access mode.
     777             :      */
     778       99462 :     GDALAccess GetAccess() const
     779             :     {
     780       99462 :         return eAccess;
     781             :     }
     782             : 
     783             :     int GetShared() const;
     784             :     void MarkAsShared();
     785             : 
     786             :     void MarkSuppressOnClose();
     787             :     void UnMarkSuppressOnClose();
     788             : 
     789             :     /** Return MarkSuppressOnClose flag.
     790             :     * @return MarkSuppressOnClose flag.
     791             :     */
     792     3361184 :     bool IsMarkedSuppressOnClose()
     793             :     {
     794     3361184 :         return bSuppressOnClose;
     795             :     }
     796             : 
     797             :     /** Return open options.
     798             :      * @return open options.
     799             :      */
     800        5888 :     char **GetOpenOptions()
     801             :     {
     802        5888 :         return papszOpenOptions;
     803             :     }
     804             : 
     805             :     static GDALDataset **GetOpenDatasets(int *pnDatasetCount);
     806             : 
     807             :     CPLErr BuildOverviews(const char *, int, const int *, int, const int *,
     808             :                           GDALProgressFunc, void *,
     809             :                           CSLConstList papszOptions
     810             : #ifndef DOXYGEN_SKIP
     811             :                               OPTIONAL_OUTSIDE_GDAL(nullptr)
     812             : #endif
     813             :     );
     814             : 
     815             : #ifndef DOXYGEN_XML
     816             :     void ReportError(CPLErr eErrClass, CPLErrorNum err_no, const char *fmt,
     817             :                      ...) const CPL_PRINT_FUNC_FORMAT(4, 5);
     818             : 
     819             :     static void ReportError(const char *pszDSName, CPLErr eErrClass,
     820             :                             CPLErrorNum err_no, const char *fmt, ...)
     821             :         CPL_PRINT_FUNC_FORMAT(4, 5);
     822             : #endif
     823             : 
     824             :     char **GetMetadata(const char *pszDomain = "") override;
     825             : 
     826             : // Only defined when Doxygen enabled
     827             : #ifdef DOXYGEN_SKIP
     828             :     CPLErr SetMetadata(char **papszMetadata, const char *pszDomain) override;
     829             :     CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
     830             :                            const char *pszDomain) override;
     831             : #endif
     832             : 
     833             :     char **GetMetadataDomainList() override;
     834             : 
     835             :     virtual void ClearStatistics();
     836             : 
     837             :     /** Convert a GDALDataset* to a GDALDatasetH.
     838             :      * @since GDAL 2.3
     839             :      */
     840       19720 :     static inline GDALDatasetH ToHandle(GDALDataset *poDS)
     841             :     {
     842       19720 :         return static_cast<GDALDatasetH>(poDS);
     843             :     }
     844             : 
     845             :     /** Convert a GDALDatasetH to a GDALDataset*.
     846             :      * @since GDAL 2.3
     847             :      */
     848     1280544 :     static inline GDALDataset *FromHandle(GDALDatasetH hDS)
     849             :     {
     850     1280544 :         return static_cast<GDALDataset *>(hDS);
     851             :     }
     852             : 
     853             :     /** @see GDALOpenEx().
     854             :      * @since GDAL 2.3
     855             :      */
     856       20435 :     static GDALDataset *Open(const char *pszFilename,
     857             :                              unsigned int nOpenFlags = 0,
     858             :                              const char *const *papszAllowedDrivers = nullptr,
     859             :                              const char *const *papszOpenOptions = nullptr,
     860             :                              const char *const *papszSiblingFiles = nullptr)
     861             :     {
     862       20435 :         return FromHandle(GDALOpenEx(pszFilename, nOpenFlags,
     863             :                                      papszAllowedDrivers, papszOpenOptions,
     864       20435 :                                      papszSiblingFiles));
     865             :     }
     866             : 
     867             :     /** Object returned by GetFeatures() iterators */
     868             :     struct FeatureLayerPair
     869             :     {
     870             :         /** Unique pointer to a OGRFeature. */
     871             :         OGRFeatureUniquePtr feature{};
     872             : 
     873             :         /** Layer to which the feature belongs to. */
     874             :         OGRLayer *layer = nullptr;
     875             :     };
     876             : 
     877             :     //! @cond Doxygen_Suppress
     878             :     // SetEnableOverviews() only to be used by GDALOverviewDataset
     879             :     void SetEnableOverviews(bool bEnable);
     880             : 
     881             :     // Only to be used by driver's GetOverviewCount() method.
     882             :     bool AreOverviewsEnabled() const;
     883             :     //! @endcond
     884             : 
     885             :   private:
     886             :     class Private;
     887             :     Private *m_poPrivate;
     888             : 
     889             :     CPL_INTERNAL OGRLayer *BuildLayerFromSelectInfo(
     890             :         swq_select *psSelectInfo, OGRGeometry *poSpatialFilter,
     891             :         const char *pszDialect, swq_select_parse_options *poSelectParseOptions);
     892             :     CPLStringList oDerivedMetadataList{};
     893             : 
     894             :   public:
     895             :     virtual int GetLayerCount();
     896             :     virtual OGRLayer *GetLayer(int iLayer);
     897             : 
     898             :     virtual bool IsLayerPrivate(int iLayer) const;
     899             : 
     900             :     /** Class returned by GetLayers() that acts as a range of layers.
     901             :      * @since GDAL 2.3
     902             :      */
     903             :     class CPL_DLL Layers
     904             :     {
     905             :       private:
     906             :         friend class GDALDataset;
     907             :         GDALDataset *m_poSelf;
     908             : 
     909          12 :         CPL_INTERNAL explicit Layers(GDALDataset *poSelf) : m_poSelf(poSelf)
     910             :         {
     911          12 :         }
     912             : 
     913             :       public:
     914             :         /** Layer iterator.
     915             :          * @since GDAL 2.3
     916             :          */
     917          32 :         class CPL_DLL Iterator
     918             :         {
     919             :             struct Private;
     920             :             std::unique_ptr<Private> m_poPrivate;
     921             : 
     922             :           public:
     923             :             using value_type = OGRLayer *; /**< value_type */
     924             :             using reference = OGRLayer *;  /**< reference */
     925             :             using difference_type = void;  /**< difference_type */
     926             :             using pointer = void;          /**< pointer */
     927             :             using iterator_category =
     928             :                 std::input_iterator_tag; /**< iterator_category */
     929             : 
     930             :             Iterator(); /**< Default constructor */
     931             :             Iterator(GDALDataset *poDS, bool bStart); /**< Constructor */
     932             :             Iterator(const Iterator &oOther);         /**< Copy constructor */
     933             :             Iterator(Iterator &&oOther) noexcept;     /**< Move constructor */
     934             :             ~Iterator();                              /**< Destructor */
     935             : 
     936             :             Iterator &
     937             :             operator=(const Iterator &oOther); /**< Assignment operator */
     938             :             Iterator &operator=(
     939             :                 Iterator &&oOther) noexcept; /**< Move assignment operator */
     940             : 
     941             :             OGRLayer *operator*() const; /**< Dereference operator */
     942             :             Iterator &operator++();      /**< Pre-increment operator */
     943             :             Iterator operator++(int);    /**< Post-increment operator */
     944             :             bool operator!=(const Iterator &it)
     945             :                 const; /**< Difference comparison operator */
     946             :         };
     947             : 
     948             :         Iterator begin() const;
     949             :         Iterator end() const;
     950             : 
     951             :         size_t size() const;
     952             : 
     953             :         OGRLayer *operator[](int iLayer);
     954             :         OGRLayer *operator[](size_t iLayer);
     955             :         OGRLayer *operator[](const char *pszLayername);
     956             :     };
     957             : 
     958             :     Layers GetLayers();
     959             : 
     960             :     virtual OGRLayer *GetLayerByName(const char *);
     961             :     virtual OGRErr DeleteLayer(int iLayer);
     962             : 
     963             :     virtual void ResetReading();
     964             :     virtual OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer,
     965             :                                        double *pdfProgressPct,
     966             :                                        GDALProgressFunc pfnProgress,
     967             :                                        void *pProgressData);
     968             : 
     969             :     /** Class returned by GetFeatures() that act as a container for vector
     970             :      * features. */
     971             :     class CPL_DLL Features
     972             :     {
     973             :       private:
     974             :         friend class GDALDataset;
     975             :         GDALDataset *m_poSelf;
     976             : 
     977           2 :         CPL_INTERNAL explicit Features(GDALDataset *poSelf) : m_poSelf(poSelf)
     978             :         {
     979           2 :         }
     980             : 
     981           4 :         class CPL_DLL Iterator
     982             :         {
     983             :             struct Private;
     984             :             std::unique_ptr<Private> m_poPrivate;
     985             : 
     986             :           public:
     987             :             Iterator(GDALDataset *poDS, bool bStart);
     988             :             Iterator(const Iterator &oOther);  // declared but not defined.
     989             :                                                // Needed for gcc 5.4 at least
     990             :             Iterator(Iterator &&oOther) noexcept;  // declared but not defined.
     991             :                 // Needed for gcc 5.4 at least
     992             :             ~Iterator();
     993             :             const FeatureLayerPair &operator*() const;
     994             :             Iterator &operator++();
     995             :             bool operator!=(const Iterator &it) const;
     996             :         };
     997             : 
     998             :       public:
     999             :         const Iterator begin() const;
    1000             : 
    1001             :         const Iterator end() const;
    1002             :     };
    1003             : 
    1004             :     Features GetFeatures();
    1005             : 
    1006             :     virtual int TestCapability(const char *);
    1007             : 
    1008             :     virtual std::vector<std::string>
    1009             :     GetFieldDomainNames(CSLConstList papszOptions = nullptr) const;
    1010             : 
    1011             :     virtual const OGRFieldDomain *GetFieldDomain(const std::string &name) const;
    1012             : 
    1013             :     virtual bool AddFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain,
    1014             :                                 std::string &failureReason);
    1015             : 
    1016             :     virtual bool DeleteFieldDomain(const std::string &name,
    1017             :                                    std::string &failureReason);
    1018             : 
    1019             :     virtual bool UpdateFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain,
    1020             :                                    std::string &failureReason);
    1021             : 
    1022             :     virtual std::vector<std::string>
    1023             :     GetRelationshipNames(CSLConstList papszOptions = nullptr) const;
    1024             : 
    1025             :     virtual const GDALRelationship *
    1026             :     GetRelationship(const std::string &name) const;
    1027             : 
    1028             :     virtual bool
    1029             :     AddRelationship(std::unique_ptr<GDALRelationship> &&relationship,
    1030             :                     std::string &failureReason);
    1031             : 
    1032             :     virtual bool DeleteRelationship(const std::string &name,
    1033             :                                     std::string &failureReason);
    1034             : 
    1035             :     virtual bool
    1036             :     UpdateRelationship(std::unique_ptr<GDALRelationship> &&relationship,
    1037             :                        std::string &failureReason);
    1038             : 
    1039             :     //! @cond Doxygen_Suppress
    1040             :     OGRLayer *CreateLayer(const char *pszName);
    1041             : 
    1042             :     OGRLayer *CreateLayer(const char *pszName, std::nullptr_t);
    1043             :     //! @endcond
    1044             : 
    1045             :     OGRLayer *CreateLayer(const char *pszName,
    1046             :                           const OGRSpatialReference *poSpatialRef,
    1047             :                           OGRwkbGeometryType eGType = wkbUnknown,
    1048             :                           CSLConstList papszOptions = nullptr);
    1049             : 
    1050             :     OGRLayer *CreateLayer(const char *pszName,
    1051             :                           const OGRGeomFieldDefn *poGeomFieldDefn,
    1052             :                           CSLConstList papszOptions = nullptr);
    1053             : 
    1054             :     virtual OGRLayer *CopyLayer(OGRLayer *poSrcLayer, const char *pszNewName,
    1055             :                                 char **papszOptions = nullptr);
    1056             : 
    1057             :     virtual OGRStyleTable *GetStyleTable();
    1058             :     virtual void SetStyleTableDirectly(OGRStyleTable *poStyleTable);
    1059             : 
    1060             :     virtual void SetStyleTable(OGRStyleTable *poStyleTable);
    1061             : 
    1062             :     virtual OGRLayer *ExecuteSQL(const char *pszStatement,
    1063             :                                  OGRGeometry *poSpatialFilter,
    1064             :                                  const char *pszDialect);
    1065             :     virtual void ReleaseResultSet(OGRLayer *poResultsSet);
    1066             :     virtual OGRErr AbortSQL();
    1067             : 
    1068             :     int GetRefCount() const;
    1069             :     int GetSummaryRefCount() const;
    1070             :     OGRErr Release();
    1071             : 
    1072             :     virtual OGRErr StartTransaction(int bForce = FALSE);
    1073             :     virtual OGRErr CommitTransaction();
    1074             :     virtual OGRErr RollbackTransaction();
    1075             : 
    1076             :     virtual std::shared_ptr<GDALGroup> GetRootGroup() const;
    1077             : 
    1078             :     //! @cond Doxygen_Suppress
    1079             :     static int IsGenericSQLDialect(const char *pszDialect);
    1080             : 
    1081             :     // Semi-public methods. Only to be used by in-tree drivers.
    1082             :     GDALSQLParseInfo *
    1083             :     BuildParseInfo(swq_select *psSelectInfo,
    1084             :                    swq_select_parse_options *poSelectParseOptions);
    1085             :     static void DestroyParseInfo(GDALSQLParseInfo *psParseInfo);
    1086             :     OGRLayer *ExecuteSQL(const char *pszStatement, OGRGeometry *poSpatialFilter,
    1087             :                          const char *pszDialect,
    1088             :                          swq_select_parse_options *poSelectParseOptions);
    1089             :     //! @endcond
    1090             : 
    1091             :   protected:
    1092             :     virtual OGRLayer *ICreateLayer(const char *pszName,
    1093             :                                    const OGRGeomFieldDefn *poGeomFieldDefn,
    1094             :                                    CSLConstList papszOptions);
    1095             : 
    1096             :     //! @cond Doxygen_Suppress
    1097             :     OGRErr ProcessSQLCreateIndex(const char *);
    1098             :     OGRErr ProcessSQLDropIndex(const char *);
    1099             :     OGRErr ProcessSQLDropTable(const char *);
    1100             :     OGRErr ProcessSQLAlterTableAddColumn(const char *);
    1101             :     OGRErr ProcessSQLAlterTableDropColumn(const char *);
    1102             :     OGRErr ProcessSQLAlterTableAlterColumn(const char *);
    1103             :     OGRErr ProcessSQLAlterTableRenameColumn(const char *);
    1104             : 
    1105             :     OGRStyleTable *m_poStyleTable = nullptr;
    1106             : 
    1107             :     friend class GDALProxyPoolDataset;
    1108             :     //! @endcond
    1109             : 
    1110             :   private:
    1111             :     CPL_DISALLOW_COPY_ASSIGN(GDALDataset)
    1112             : };
    1113             : 
    1114             : //! @cond Doxygen_Suppress
    1115             : struct CPL_DLL GDALDatasetUniquePtrDeleter
    1116             : {
    1117          59 :     void operator()(GDALDataset *poDataset) const
    1118             :     {
    1119          59 :         GDALClose(poDataset);
    1120          59 :     }
    1121             : };
    1122             : 
    1123             : //! @endcond
    1124             : 
    1125             : //! @cond Doxygen_Suppress
    1126             : struct CPL_DLL GDALDatasetUniquePtrReleaser
    1127             : {
    1128         284 :     void operator()(GDALDataset *poDataset) const
    1129             :     {
    1130         284 :         if (poDataset)
    1131         282 :             poDataset->Release();
    1132         284 :     }
    1133             : };
    1134             : 
    1135             : //! @endcond
    1136             : 
    1137             : /** Unique pointer type for GDALDataset.
    1138             :  * Appropriate for use on datasets open in non-shared mode and onto which
    1139             :  * reference counter has not been manually modified.
    1140             :  * @since GDAL 2.3
    1141             :  */
    1142             : using GDALDatasetUniquePtr =
    1143             :     std::unique_ptr<GDALDataset, GDALDatasetUniquePtrDeleter>;
    1144             : 
    1145             : /* ******************************************************************** */
    1146             : /*                           GDALRasterBlock                            */
    1147             : /* ******************************************************************** */
    1148             : 
    1149             : /** A single raster block in the block cache.
    1150             :  *
    1151             :  * And the global block manager that manages a least-recently-used list of
    1152             :  * blocks from various datasets/bands */
    1153             : class CPL_DLL GDALRasterBlock
    1154             : {
    1155             :     friend class GDALAbstractBandBlockCache;
    1156             : 
    1157             :     GDALDataType eType;
    1158             : 
    1159             :     bool bDirty;
    1160             :     volatile int nLockCount;
    1161             : 
    1162             :     int nXOff;
    1163             :     int nYOff;
    1164             : 
    1165             :     int nXSize;
    1166             :     int nYSize;
    1167             : 
    1168             :     void *pData;
    1169             : 
    1170             :     GDALRasterBand *poBand;
    1171             : 
    1172             :     GDALRasterBlock *poNext;
    1173             :     GDALRasterBlock *poPrevious;
    1174             : 
    1175             :     bool bMustDetach;
    1176             : 
    1177             :     CPL_INTERNAL void Detach_unlocked(void);
    1178             :     CPL_INTERNAL void Touch_unlocked(void);
    1179             : 
    1180             :     CPL_INTERNAL void RecycleFor(int nXOffIn, int nYOffIn);
    1181             : 
    1182             :   public:
    1183             :     GDALRasterBlock(GDALRasterBand *, int, int);
    1184             :     GDALRasterBlock(int nXOffIn, int nYOffIn); /* only for lookup purpose */
    1185             :     virtual ~GDALRasterBlock();
    1186             : 
    1187             :     CPLErr Internalize(void);
    1188             :     void Touch(void);
    1189             :     void MarkDirty(void);
    1190             :     void MarkClean(void);
    1191             : 
    1192             :     /** Increment the lock count */
    1193     9388490 :     int AddLock(void)
    1194             :     {
    1195     9388490 :         return CPLAtomicInc(&nLockCount);
    1196             :     }
    1197             : 
    1198             :     /** Decrement the lock count */
    1199     9388489 :     int DropLock(void)
    1200             :     {
    1201     9388489 :         return CPLAtomicDec(&nLockCount);
    1202             :     }
    1203             : 
    1204             :     void Detach();
    1205             : 
    1206             :     CPLErr Write();
    1207             : 
    1208             :     /** Return the data type
    1209             :      * @return data type
    1210             :      */
    1211       28407 :     GDALDataType GetDataType() const
    1212             :     {
    1213       28407 :         return eType;
    1214             :     }
    1215             : 
    1216             :     /** Return the x offset of the top-left corner of the block
    1217             :      * @return x offset
    1218             :      */
    1219    11930900 :     int GetXOff() const
    1220             :     {
    1221    11930900 :         return nXOff;
    1222             :     }
    1223             : 
    1224             :     /** Return the y offset of the top-left corner of the block
    1225             :      * @return y offset
    1226             :      */
    1227   482769000 :     int GetYOff() const
    1228             :     {
    1229   482769000 :         return nYOff;
    1230             :     }
    1231             : 
    1232             :     /** Return the width of the block
    1233             :      * @return width
    1234             :      */
    1235             :     int GetXSize() const
    1236             :     {
    1237             :         return nXSize;
    1238             :     }
    1239             : 
    1240             :     /** Return the height of the block
    1241             :      * @return height
    1242             :      */
    1243             :     int GetYSize() const
    1244             :     {
    1245             :         return nYSize;
    1246             :     }
    1247             : 
    1248             :     /** Return the dirty flag
    1249             :      * @return dirty flag
    1250             :      */
    1251     3463110 :     int GetDirty() const
    1252             :     {
    1253     3463110 :         return bDirty;
    1254             :     }
    1255             : 
    1256             :     /** Return the data buffer
    1257             :      * @return data buffer
    1258             :      */
    1259    12475477 :     void *GetDataRef(void)
    1260             :     {
    1261    12475477 :         return pData;
    1262             :     }
    1263             : 
    1264             :     /** Return the block size in bytes
    1265             :      * @return block size.
    1266             :      */
    1267     5959870 :     GPtrDiff_t GetBlockSize() const
    1268             :     {
    1269     5959870 :         return static_cast<GPtrDiff_t>(nXSize) * nYSize *
    1270     5959870 :                GDALGetDataTypeSizeBytes(eType);
    1271             :     }
    1272             : 
    1273             :     int TakeLock();
    1274             :     int DropLockForRemovalFromStorage();
    1275             : 
    1276             :     /// @brief Accessor to source GDALRasterBand object.
    1277             :     /// @return source raster band of the raster block.
    1278       59194 :     GDALRasterBand *GetBand()
    1279             :     {
    1280       59194 :         return poBand;
    1281             :     }
    1282             : 
    1283             :     static void FlushDirtyBlocks();
    1284             :     static int FlushCacheBlock(int bDirtyBlocksOnly = FALSE);
    1285             :     static void Verify();
    1286             : 
    1287             :     static void EnterDisableDirtyBlockFlush();
    1288             :     static void LeaveDisableDirtyBlockFlush();
    1289             : 
    1290             : #ifdef notdef
    1291             :     static void CheckNonOrphanedBlocks(GDALRasterBand *poBand);
    1292             :     void DumpBlock();
    1293             :     static void DumpAll();
    1294             : #endif
    1295             : 
    1296             :     /* Should only be called by GDALDestroyDriverManager() */
    1297             :     //! @cond Doxygen_Suppress
    1298             :     CPL_INTERNAL static void DestroyRBMutex();
    1299             :     //! @endcond
    1300             : 
    1301             :   private:
    1302             :     CPL_DISALLOW_COPY_ASSIGN(GDALRasterBlock)
    1303             : };
    1304             : 
    1305             : /* ******************************************************************** */
    1306             : /*                             GDALColorTable                           */
    1307             : /* ******************************************************************** */
    1308             : 
    1309             : /** A color table / palette. */
    1310             : 
    1311        1341 : class CPL_DLL GDALColorTable
    1312             : {
    1313             :     GDALPaletteInterp eInterp;
    1314             : 
    1315             :     std::vector<GDALColorEntry> aoEntries{};
    1316             : 
    1317             :   public:
    1318             :     explicit GDALColorTable(GDALPaletteInterp = GPI_RGB);
    1319             :     ~GDALColorTable();
    1320             : 
    1321             :     GDALColorTable *Clone() const;
    1322             :     int IsSame(const GDALColorTable *poOtherCT) const;
    1323             : 
    1324             :     GDALPaletteInterp GetPaletteInterpretation() const;
    1325             : 
    1326             :     int GetColorEntryCount() const;
    1327             :     const GDALColorEntry *GetColorEntry(int) const;
    1328             :     int GetColorEntryAsRGB(int, GDALColorEntry *) const;
    1329             :     void SetColorEntry(int, const GDALColorEntry *);
    1330             :     int CreateColorRamp(int, const GDALColorEntry *, int,
    1331             :                         const GDALColorEntry *);
    1332             :     bool IsIdentity() const;
    1333             : 
    1334             :     /** Convert a GDALColorTable* to a GDALRasterBandH.
    1335             :      * @since GDAL 2.3
    1336             :      */
    1337        1639 :     static inline GDALColorTableH ToHandle(GDALColorTable *poCT)
    1338             :     {
    1339        1639 :         return static_cast<GDALColorTableH>(poCT);
    1340             :     }
    1341             : 
    1342             :     /** Convert a GDALColorTableH to a GDALColorTable*.
    1343             :      * @since GDAL 2.3
    1344             :      */
    1345       12847 :     static inline GDALColorTable *FromHandle(GDALColorTableH hCT)
    1346             :     {
    1347       12847 :         return static_cast<GDALColorTable *>(hCT);
    1348             :     }
    1349             : };
    1350             : 
    1351             : /* ******************************************************************** */
    1352             : /*                       GDALAbstractBandBlockCache                     */
    1353             : /* ******************************************************************** */
    1354             : 
    1355             : //! @cond Doxygen_Suppress
    1356             : 
    1357             : //! This manages how a raster band store its cached block.
    1358             : // only used by GDALRasterBand implementation.
    1359             : 
    1360             : class GDALAbstractBandBlockCache
    1361             : {
    1362             :     // List of blocks that can be freed or recycled, and its lock
    1363             :     CPLLock *hSpinLock = nullptr;
    1364             :     GDALRasterBlock *psListBlocksToFree = nullptr;
    1365             : 
    1366             :     // Band keep alive counter, and its lock & condition
    1367             :     CPLCond *hCond = nullptr;
    1368             :     CPLMutex *hCondMutex = nullptr;
    1369             :     volatile int nKeepAliveCounter = 0;
    1370             : 
    1371             :     volatile int m_nDirtyBlocks = 0;
    1372             : 
    1373             :     CPL_DISALLOW_COPY_ASSIGN(GDALAbstractBandBlockCache)
    1374             : 
    1375             :   protected:
    1376             :     GDALRasterBand *poBand;
    1377             : 
    1378             :     int m_nInitialDirtyBlocksInFlushCache = 0;
    1379             :     int m_nLastTick = -1;
    1380             :     size_t m_nWriteDirtyBlocksDisabled = 0;
    1381             : 
    1382             :     void FreeDanglingBlocks();
    1383             :     void UnreferenceBlockBase();
    1384             : 
    1385             :     void StartDirtyBlockFlushingLog();
    1386             :     void UpdateDirtyBlockFlushingLog();
    1387             :     void EndDirtyBlockFlushingLog();
    1388             : 
    1389             :   public:
    1390             :     explicit GDALAbstractBandBlockCache(GDALRasterBand *poBand);
    1391             :     virtual ~GDALAbstractBandBlockCache();
    1392             : 
    1393             :     GDALRasterBlock *CreateBlock(int nXBlockOff, int nYBlockOff);
    1394             :     void AddBlockToFreeList(GDALRasterBlock *);
    1395             :     void IncDirtyBlocks(int nInc);
    1396             :     void WaitCompletionPendingTasks();
    1397             : 
    1398           1 :     void EnableDirtyBlockWriting()
    1399             :     {
    1400           1 :         --m_nWriteDirtyBlocksDisabled;
    1401           1 :     }
    1402             : 
    1403        2422 :     void DisableDirtyBlockWriting()
    1404             :     {
    1405        2422 :         ++m_nWriteDirtyBlocksDisabled;
    1406        2422 :     }
    1407             : 
    1408           0 :     bool HasDirtyBlocks() const
    1409             :     {
    1410           0 :         return m_nDirtyBlocks > 0;
    1411             :     }
    1412             : 
    1413             :     virtual bool Init() = 0;
    1414             :     virtual bool IsInitOK() = 0;
    1415             :     virtual CPLErr FlushCache() = 0;
    1416             :     virtual CPLErr AdoptBlock(GDALRasterBlock *poBlock) = 0;
    1417             :     virtual GDALRasterBlock *TryGetLockedBlockRef(int nXBlockOff,
    1418             :                                                   int nYBlockYOff) = 0;
    1419             :     virtual CPLErr UnreferenceBlock(GDALRasterBlock *poBlock) = 0;
    1420             :     virtual CPLErr FlushBlock(int nXBlockOff, int nYBlockOff,
    1421             :                               int bWriteDirtyBlock) = 0;
    1422             : };
    1423             : 
    1424             : GDALAbstractBandBlockCache *
    1425             : GDALArrayBandBlockCacheCreate(GDALRasterBand *poBand);
    1426             : GDALAbstractBandBlockCache *
    1427             : GDALHashSetBandBlockCacheCreate(GDALRasterBand *poBand);
    1428             : 
    1429             : //! @endcond
    1430             : 
    1431             : /* ******************************************************************** */
    1432             : /*                            GDALRasterBand                            */
    1433             : /* ******************************************************************** */
    1434             : 
    1435             : class GDALMDArray;
    1436             : 
    1437             : /** Range of values found in a mask band */
    1438             : typedef enum
    1439             : {
    1440             :     GMVR_UNKNOWN, /*! Unknown (can also be used for any values between 0 and 255
    1441             :                      for a Byte band) */
    1442             :     GMVR_0_AND_1_ONLY,   /*! Only 0 and 1 */
    1443             :     GMVR_0_AND_255_ONLY, /*! Only 0 and 255 */
    1444             : } GDALMaskValueRange;
    1445             : 
    1446             : /** Suggested/most efficient access pattern to blocks. */
    1447             : typedef int GDALSuggestedBlockAccessPattern;
    1448             : 
    1449             : /** Unknown, or no particular read order is suggested. */
    1450             : constexpr GDALSuggestedBlockAccessPattern GSBAP_UNKNOWN = 0;
    1451             : 
    1452             : /** Random access to blocks is efficient. */
    1453             : constexpr GDALSuggestedBlockAccessPattern GSBAP_RANDOM = 1;
    1454             : 
    1455             : /** Reading by strips from top to bottom is the most efficient. */
    1456             : constexpr GDALSuggestedBlockAccessPattern GSBAP_TOP_TO_BOTTOM = 2;
    1457             : 
    1458             : /** Reading by strips from bottom to top is the most efficient. */
    1459             : constexpr GDALSuggestedBlockAccessPattern GSBAP_BOTTOM_TO_TOP = 3;
    1460             : 
    1461             : /** Reading the largest chunk from the raster is the most efficient (can be
    1462             :  * combined with above values). */
    1463             : constexpr GDALSuggestedBlockAccessPattern GSBAP_LARGEST_CHUNK_POSSIBLE = 0x100;
    1464             : 
    1465             : /** A single raster band (or channel). */
    1466             : 
    1467             : class CPL_DLL GDALRasterBand : public GDALMajorObject
    1468             : {
    1469             :   private:
    1470             :     friend class GDALArrayBandBlockCache;
    1471             :     friend class GDALHashSetBandBlockCache;
    1472             :     friend class GDALRasterBlock;
    1473             :     friend class GDALDataset;
    1474             : 
    1475             :     CPLErr eFlushBlockErr = CE_None;
    1476             :     GDALAbstractBandBlockCache *poBandBlockCache = nullptr;
    1477             : 
    1478             :     CPL_INTERNAL void SetFlushBlockErr(CPLErr eErr);
    1479             :     CPL_INTERNAL CPLErr UnreferenceBlock(GDALRasterBlock *poBlock);
    1480             :     CPL_INTERNAL void IncDirtyBlocks(int nInc);
    1481             : 
    1482             :   protected:
    1483             :     //! @cond Doxygen_Suppress
    1484             :     GDALDataset *poDS = nullptr;
    1485             :     int nBand = 0; /* 1 based */
    1486             : 
    1487             :     int nRasterXSize = 0;
    1488             :     int nRasterYSize = 0;
    1489             : 
    1490             :     GDALDataType eDataType = GDT_Byte;
    1491             :     GDALAccess eAccess = GA_ReadOnly;
    1492             : 
    1493             :     /* stuff related to blocking, and raster cache */
    1494             :     int nBlockXSize = -1;
    1495             :     int nBlockYSize = -1;
    1496             :     int nBlocksPerRow = 0;
    1497             :     int nBlocksPerColumn = 0;
    1498             : 
    1499             :     int nBlockReads = 0;
    1500             :     int bForceCachedIO = 0;
    1501             : 
    1502             :     class GDALRasterBandOwnedOrNot
    1503             :     {
    1504             :       public:
    1505     1040980 :         GDALRasterBandOwnedOrNot()
    1506     1040980 :         {
    1507     1040940 :         }
    1508             : 
    1509             :         GDALRasterBandOwnedOrNot(GDALRasterBand *poBand, bool bOwned)
    1510             :             : m_poBandOwned(bOwned ? poBand : nullptr),
    1511             :               m_poBandRef(bOwned ? nullptr : poBand)
    1512             :         {
    1513             :         }
    1514             : 
    1515     1041140 :         void reset()
    1516             :         {
    1517     1041140 :             m_poBandOwned.reset();
    1518     1041130 :             m_poBandRef = nullptr;
    1519     1041130 :         }
    1520             : 
    1521       22731 :         void reset(GDALRasterBand *poBand, bool bOwned)
    1522             :         {
    1523       22731 :             m_poBandOwned.reset(bOwned ? poBand : nullptr);
    1524       22731 :             m_poBandRef = bOwned ? nullptr : poBand;
    1525       22731 :         }
    1526             : 
    1527       34529 :         GDALRasterBand *get()
    1528             :         {
    1529       34529 :             return static_cast<GDALRasterBand *>(*this);
    1530             :         }
    1531             : 
    1532        6235 :         bool IsOwned() const
    1533             :         {
    1534        6235 :             return m_poBandOwned != nullptr;
    1535             :         }
    1536             : 
    1537      132019 :         operator GDALRasterBand *()
    1538             :         {
    1539      132019 :             return m_poBandOwned ? m_poBandOwned.get() : m_poBandRef;
    1540             :         }
    1541             : 
    1542             :       private:
    1543             :         CPL_DISALLOW_COPY_ASSIGN(GDALRasterBandOwnedOrNot)
    1544             :         std::unique_ptr<GDALRasterBand> m_poBandOwned{};
    1545             :         GDALRasterBand *m_poBandRef = nullptr;
    1546             :     };
    1547             : 
    1548             :     GDALRasterBandOwnedOrNot poMask{};
    1549             :     bool m_bEnablePixelTypeSignedByteWarning =
    1550             :         true;  // Remove me in GDAL 4.0. See GetMetadataItem() implementation
    1551             :     int nMaskFlags = 0;
    1552             : 
    1553             :     void InvalidateMaskBand();
    1554             : 
    1555             :     friend class GDALProxyRasterBand;
    1556             :     friend class GDALDefaultOverviews;
    1557             : 
    1558             :     CPLErr
    1559             :     RasterIOResampled(GDALRWFlag, int, int, int, int, void *, int, int,
    1560             :                       GDALDataType, GSpacing, GSpacing,
    1561             :                       GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
    1562             : 
    1563             :     int EnterReadWrite(GDALRWFlag eRWFlag);
    1564             :     void LeaveReadWrite();
    1565             :     void InitRWLock();
    1566             :     void SetValidPercent(GUIntBig nSampleCount, GUIntBig nValidCount);
    1567             : 
    1568             :     //! @endcond
    1569             : 
    1570             :   protected:
    1571             :     virtual CPLErr IReadBlock(int nBlockXOff, int nBlockYOff, void *pData) = 0;
    1572             :     virtual CPLErr IWriteBlock(int nBlockXOff, int nBlockYOff, void *pData);
    1573             : 
    1574             :     virtual CPLErr
    1575             :     IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int, GDALDataType,
    1576             :               GSpacing, GSpacing,
    1577             :               GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
    1578             : 
    1579             :     virtual int IGetDataCoverageStatus(int nXOff, int nYOff, int nXSize,
    1580             :                                        int nYSize, int nMaskFlagStop,
    1581             :                                        double *pdfDataPct);
    1582             :     //! @cond Doxygen_Suppress
    1583             :     CPLErr
    1584             :     OverviewRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
    1585             :                      GDALDataType, GSpacing, GSpacing,
    1586             :                      GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
    1587             : 
    1588             :     CPLErr TryOverviewRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
    1589             :                                int nXSize, int nYSize, void *pData,
    1590             :                                int nBufXSize, int nBufYSize,
    1591             :                                GDALDataType eBufType, GSpacing nPixelSpace,
    1592             :                                GSpacing nLineSpace,
    1593             :                                GDALRasterIOExtraArg *psExtraArg, int *pbTried);
    1594             : 
    1595             :     int InitBlockInfo();
    1596             : 
    1597             :     void AddBlockToFreeList(GDALRasterBlock *);
    1598             : 
    1599       83091 :     bool HasBlockCache() const
    1600             :     {
    1601       83091 :         return poBandBlockCache != nullptr;
    1602             :     }
    1603             : 
    1604          17 :     bool HasDirtyBlocks() const
    1605             :     {
    1606          17 :         return poBandBlockCache && poBandBlockCache->HasDirtyBlocks();
    1607             :     }
    1608             : 
    1609             :     //! @endcond
    1610             : 
    1611             :   public:
    1612             :     GDALRasterBand();
    1613             :     explicit GDALRasterBand(int bForceCachedIO);
    1614             : 
    1615             :     ~GDALRasterBand() override;
    1616             : 
    1617             :     int GetXSize();
    1618             :     int GetYSize();
    1619             :     int GetBand();
    1620             :     GDALDataset *GetDataset();
    1621             : 
    1622             :     GDALDataType GetRasterDataType(void);
    1623             :     void GetBlockSize(int *, int *);
    1624             :     CPLErr GetActualBlockSize(int, int, int *, int *);
    1625             : 
    1626             :     virtual GDALSuggestedBlockAccessPattern
    1627             :     GetSuggestedBlockAccessPattern() const;
    1628             : 
    1629             :     GDALAccess GetAccess();
    1630             : 
    1631             :     CPLErr RasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
    1632             :                     GDALDataType, GSpacing, GSpacing,
    1633             :                     GDALRasterIOExtraArg *psExtraArg
    1634             : #ifndef DOXYGEN_SKIP
    1635             :                         OPTIONAL_OUTSIDE_GDAL(nullptr)
    1636             : #endif
    1637             :                         ) CPL_WARN_UNUSED_RESULT;
    1638             :     CPLErr ReadBlock(int, int, void *) CPL_WARN_UNUSED_RESULT;
    1639             : 
    1640             :     CPLErr WriteBlock(int, int, void *) CPL_WARN_UNUSED_RESULT;
    1641             : 
    1642             :     GDALRasterBlock *
    1643             :     GetLockedBlockRef(int nXBlockOff, int nYBlockOff,
    1644             :                       int bJustInitialize = FALSE) CPL_WARN_UNUSED_RESULT;
    1645             :     GDALRasterBlock *TryGetLockedBlockRef(int nXBlockOff, int nYBlockYOff)
    1646             :         CPL_WARN_UNUSED_RESULT;
    1647             :     CPLErr FlushBlock(int, int, int bWriteDirtyBlock = TRUE);
    1648             : 
    1649             :     unsigned char *
    1650             :     GetIndexColorTranslationTo(/* const */ GDALRasterBand *poReferenceBand,
    1651             :                                unsigned char *pTranslationTable = nullptr,
    1652             :                                int *pApproximateMatching = nullptr);
    1653             : 
    1654             :     // New OpengIS CV_SampleDimension stuff.
    1655             : 
    1656             :     virtual CPLErr FlushCache(bool bAtClosing = false);
    1657             :     virtual CPLErr DropCache();
    1658             :     virtual char **GetCategoryNames();
    1659             :     virtual double GetNoDataValue(int *pbSuccess = nullptr);
    1660             :     virtual int64_t GetNoDataValueAsInt64(int *pbSuccess = nullptr);
    1661             :     virtual uint64_t GetNoDataValueAsUInt64(int *pbSuccess = nullptr);
    1662             :     virtual double GetMinimum(int *pbSuccess = nullptr);
    1663             :     virtual double GetMaximum(int *pbSuccess = nullptr);
    1664             :     virtual double GetOffset(int *pbSuccess = nullptr);
    1665             :     virtual double GetScale(int *pbSuccess = nullptr);
    1666             :     virtual const char *GetUnitType();
    1667             :     virtual GDALColorInterp GetColorInterpretation();
    1668             :     virtual GDALColorTable *GetColorTable();
    1669             :     virtual CPLErr Fill(double dfRealValue, double dfImaginaryValue = 0);
    1670             : 
    1671             :     virtual CPLErr SetCategoryNames(char **papszNames);
    1672             :     virtual CPLErr SetNoDataValue(double dfNoData);
    1673             :     virtual CPLErr SetNoDataValueAsInt64(int64_t nNoData);
    1674             :     virtual CPLErr SetNoDataValueAsUInt64(uint64_t nNoData);
    1675             :     virtual CPLErr DeleteNoDataValue();
    1676             :     virtual CPLErr SetColorTable(GDALColorTable *poCT);
    1677             :     virtual CPLErr SetColorInterpretation(GDALColorInterp eColorInterp);
    1678             :     virtual CPLErr SetOffset(double dfNewOffset);
    1679             :     virtual CPLErr SetScale(double dfNewScale);
    1680             :     virtual CPLErr SetUnitType(const char *pszNewValue);
    1681             : 
    1682             :     virtual CPLErr GetStatistics(int bApproxOK, int bForce, double *pdfMin,
    1683             :                                  double *pdfMax, double *pdfMean,
    1684             :                                  double *padfStdDev);
    1685             :     virtual CPLErr ComputeStatistics(int bApproxOK, double *pdfMin,
    1686             :                                      double *pdfMax, double *pdfMean,
    1687             :                                      double *pdfStdDev, GDALProgressFunc,
    1688             :                                      void *pProgressData);
    1689             :     virtual CPLErr SetStatistics(double dfMin, double dfMax, double dfMean,
    1690             :                                  double dfStdDev);
    1691             :     virtual CPLErr ComputeRasterMinMax(int, double *);
    1692             : 
    1693             : // Only defined when Doxygen enabled
    1694             : #ifdef DOXYGEN_SKIP
    1695             :     CPLErr SetMetadata(char **papszMetadata, const char *pszDomain) override;
    1696             :     CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
    1697             :                            const char *pszDomain) override;
    1698             : #endif
    1699             :     virtual const char *GetMetadataItem(const char *pszName,
    1700             :                                         const char *pszDomain = "") override;
    1701             : 
    1702             :     virtual int HasArbitraryOverviews();
    1703             :     virtual int GetOverviewCount();
    1704             :     virtual GDALRasterBand *GetOverview(int);
    1705             :     virtual GDALRasterBand *GetRasterSampleOverview(GUIntBig);
    1706             :     virtual CPLErr BuildOverviews(const char *pszResampling, int nOverviews,
    1707             :                                   const int *panOverviewList,
    1708             :                                   GDALProgressFunc pfnProgress,
    1709             :                                   void *pProgressData,
    1710             :                                   CSLConstList papszOptions);
    1711             : 
    1712             :     virtual CPLErr AdviseRead(int nXOff, int nYOff, int nXSize, int nYSize,
    1713             :                               int nBufXSize, int nBufYSize,
    1714             :                               GDALDataType eBufType, char **papszOptions);
    1715             : 
    1716             :     virtual CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets,
    1717             :                                 GUIntBig *panHistogram, int bIncludeOutOfRange,
    1718             :                                 int bApproxOK, GDALProgressFunc,
    1719             :                                 void *pProgressData);
    1720             : 
    1721             :     virtual CPLErr GetDefaultHistogram(double *pdfMin, double *pdfMax,
    1722             :                                        int *pnBuckets, GUIntBig **ppanHistogram,
    1723             :                                        int bForce, GDALProgressFunc,
    1724             :                                        void *pProgressData);
    1725             :     virtual CPLErr SetDefaultHistogram(double dfMin, double dfMax, int nBuckets,
    1726             :                                        GUIntBig *panHistogram);
    1727             : 
    1728             :     virtual GDALRasterAttributeTable *GetDefaultRAT();
    1729             :     virtual CPLErr SetDefaultRAT(const GDALRasterAttributeTable *poRAT);
    1730             : 
    1731             :     virtual GDALRasterBand *GetMaskBand();
    1732             :     virtual int GetMaskFlags();
    1733             :     virtual CPLErr CreateMaskBand(int nFlagsIn);
    1734             :     virtual bool IsMaskBand() const;
    1735             :     virtual GDALMaskValueRange GetMaskValueRange() const;
    1736             : 
    1737             :     virtual CPLVirtualMem *
    1738             :     GetVirtualMemAuto(GDALRWFlag eRWFlag, int *pnPixelSpace,
    1739             :                       GIntBig *pnLineSpace,
    1740             :                       char **papszOptions) CPL_WARN_UNUSED_RESULT;
    1741             : 
    1742             :     int GetDataCoverageStatus(int nXOff, int nYOff, int nXSize, int nYSize,
    1743             :                               int nMaskFlagStop = 0,
    1744             :                               double *pdfDataPct = nullptr);
    1745             : 
    1746             :     std::shared_ptr<GDALMDArray> AsMDArray() const;
    1747             : 
    1748             : #ifndef DOXYGEN_XML
    1749             :     void ReportError(CPLErr eErrClass, CPLErrorNum err_no, const char *fmt, ...)
    1750             :         CPL_PRINT_FUNC_FORMAT(4, 5);
    1751             : #endif
    1752             : 
    1753             :     /** Convert a GDALRasterBand* to a GDALRasterBandH.
    1754             :      * @since GDAL 2.3
    1755             :      */
    1756      273912 :     static inline GDALRasterBandH ToHandle(GDALRasterBand *poBand)
    1757             :     {
    1758      273912 :         return static_cast<GDALRasterBandH>(poBand);
    1759             :     }
    1760             : 
    1761             :     /** Convert a GDALRasterBandH to a GDALRasterBand*.
    1762             :      * @since GDAL 2.3
    1763             :      */
    1764     4107856 :     static inline GDALRasterBand *FromHandle(GDALRasterBandH hBand)
    1765             :     {
    1766     4107856 :         return static_cast<GDALRasterBand *>(hBand);
    1767             :     }
    1768             : 
    1769             :     //! @cond Doxygen_Suppress
    1770             :     // Remove me in GDAL 4.0. See GetMetadataItem() implementation
    1771             :     // Internal use in GDAL only !
    1772             :     void EnablePixelTypeSignedByteWarning(bool b)
    1773             : #ifndef GDAL_COMPILATION
    1774             :         CPL_WARN_DEPRECATED("Do not use that method outside of GDAL!")
    1775             : #endif
    1776             :             ;
    1777             : 
    1778             :     //! @endcond
    1779             : 
    1780             :   private:
    1781             :     CPL_DISALLOW_COPY_ASSIGN(GDALRasterBand)
    1782             : };
    1783             : 
    1784             : //! @cond Doxygen_Suppress
    1785             : /* ******************************************************************** */
    1786             : /*                         GDALAllValidMaskBand                         */
    1787             : /* ******************************************************************** */
    1788             : 
    1789       40392 : class CPL_DLL GDALAllValidMaskBand : public GDALRasterBand
    1790             : {
    1791             :   protected:
    1792             :     CPLErr IReadBlock(int, int, void *) override;
    1793             : 
    1794             :     CPL_DISALLOW_COPY_ASSIGN(GDALAllValidMaskBand)
    1795             : 
    1796             :   public:
    1797             :     explicit GDALAllValidMaskBand(GDALRasterBand *);
    1798             :     ~GDALAllValidMaskBand() override;
    1799             : 
    1800             :     GDALRasterBand *GetMaskBand() override;
    1801             :     int GetMaskFlags() override;
    1802             : 
    1803           1 :     bool IsMaskBand() const override
    1804             :     {
    1805           1 :         return true;
    1806             :     }
    1807             : 
    1808           0 :     GDALMaskValueRange GetMaskValueRange() const override
    1809             :     {
    1810           0 :         return GMVR_0_AND_255_ONLY;
    1811             :     }
    1812             : 
    1813             :     CPLErr ComputeStatistics(int bApproxOK, double *pdfMin, double *pdfMax,
    1814             :                              double *pdfMean, double *pdfStdDev,
    1815             :                              GDALProgressFunc, void *pProgressData) override;
    1816             : };
    1817             : 
    1818             : /* ******************************************************************** */
    1819             : /*                         GDALNoDataMaskBand                           */
    1820             : /* ******************************************************************** */
    1821             : 
    1822        1470 : class CPL_DLL GDALNoDataMaskBand : public GDALRasterBand
    1823             : {
    1824             :     friend class GDALRasterBand;
    1825             :     double m_dfNoDataValue = 0;
    1826             :     int64_t m_nNoDataValueInt64 = 0;
    1827             :     uint64_t m_nNoDataValueUInt64 = 0;
    1828             :     GDALRasterBand *m_poParent = nullptr;
    1829             : 
    1830             :     CPL_DISALLOW_COPY_ASSIGN(GDALNoDataMaskBand)
    1831             : 
    1832             :   protected:
    1833             :     CPLErr IReadBlock(int, int, void *) override;
    1834             :     CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
    1835             :                      GDALDataType, GSpacing, GSpacing,
    1836             :                      GDALRasterIOExtraArg *psExtraArg) override;
    1837             : 
    1838             :   public:
    1839             :     explicit GDALNoDataMaskBand(GDALRasterBand *);
    1840             :     explicit GDALNoDataMaskBand(GDALRasterBand *, double dfNoDataValue);
    1841             :     ~GDALNoDataMaskBand() override;
    1842             : 
    1843           1 :     bool IsMaskBand() const override
    1844             :     {
    1845           1 :         return true;
    1846             :     }
    1847             : 
    1848           0 :     GDALMaskValueRange GetMaskValueRange() const override
    1849             :     {
    1850           0 :         return GMVR_0_AND_255_ONLY;
    1851             :     }
    1852             : 
    1853             :     static bool IsNoDataInRange(double dfNoDataValue, GDALDataType eDataType);
    1854             : };
    1855             : 
    1856             : /* ******************************************************************** */
    1857             : /*                  GDALNoDataValuesMaskBand                            */
    1858             : /* ******************************************************************** */
    1859             : 
    1860             : class CPL_DLL GDALNoDataValuesMaskBand : public GDALRasterBand
    1861             : {
    1862             :     double *padfNodataValues;
    1863             : 
    1864             :     CPL_DISALLOW_COPY_ASSIGN(GDALNoDataValuesMaskBand)
    1865             : 
    1866             :   protected:
    1867             :     CPLErr IReadBlock(int, int, void *) override;
    1868             : 
    1869             :   public:
    1870             :     explicit GDALNoDataValuesMaskBand(GDALDataset *);
    1871             :     ~GDALNoDataValuesMaskBand() override;
    1872             : 
    1873           0 :     bool IsMaskBand() const override
    1874             :     {
    1875           0 :         return true;
    1876             :     }
    1877             : 
    1878           0 :     GDALMaskValueRange GetMaskValueRange() const override
    1879             :     {
    1880           0 :         return GMVR_0_AND_255_ONLY;
    1881             :     }
    1882             : };
    1883             : 
    1884             : /* ******************************************************************** */
    1885             : /*                         GDALRescaledAlphaBand                        */
    1886             : /* ******************************************************************** */
    1887             : 
    1888             : class GDALRescaledAlphaBand : public GDALRasterBand
    1889             : {
    1890             :     GDALRasterBand *poParent;
    1891             :     void *pTemp;
    1892             : 
    1893             :     CPL_DISALLOW_COPY_ASSIGN(GDALRescaledAlphaBand)
    1894             : 
    1895             :   protected:
    1896             :     CPLErr IReadBlock(int, int, void *) override;
    1897             :     CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
    1898             :                      GDALDataType, GSpacing, GSpacing,
    1899             :                      GDALRasterIOExtraArg *psExtraArg) override;
    1900             : 
    1901             :   public:
    1902             :     explicit GDALRescaledAlphaBand(GDALRasterBand *);
    1903             :     ~GDALRescaledAlphaBand() override;
    1904             : 
    1905           0 :     bool IsMaskBand() const override
    1906             :     {
    1907           0 :         return true;
    1908             :     }
    1909             : };
    1910             : 
    1911             : //! @endcond
    1912             : 
    1913             : /* ******************************************************************** */
    1914             : /*                          GDALIdentifyEnum                            */
    1915             : /* ******************************************************************** */
    1916             : 
    1917             : /**
    1918             :  * Enumeration used by GDALDriver::pfnIdentify().
    1919             :  *
    1920             :  * @since GDAL 2.1
    1921             :  */
    1922             : typedef enum
    1923             : {
    1924             :     /** Identify could not determine if the file is recognized or not by the
    1925             :        probed driver. */
    1926             :     GDAL_IDENTIFY_UNKNOWN = -1,
    1927             :     /** Identify determined the file is not recognized by the probed driver. */
    1928             :     GDAL_IDENTIFY_FALSE = 0,
    1929             :     /** Identify determined the file is recognized by the probed driver. */
    1930             :     GDAL_IDENTIFY_TRUE = 1
    1931             : } GDALIdentifyEnum;
    1932             : 
    1933             : /* ******************************************************************** */
    1934             : /*                              GDALDriver                              */
    1935             : /* ******************************************************************** */
    1936             : 
    1937             : /**
    1938             :  * \brief Format specific driver.
    1939             :  *
    1940             :  * An instance of this class is created for each supported format, and
    1941             :  * manages information about the format.
    1942             :  *
    1943             :  * This roughly corresponds to a file format, though some
    1944             :  * drivers may be gateways to many formats through a secondary
    1945             :  * multi-library.
    1946             :  */
    1947             : 
    1948      285492 : class CPL_DLL GDALDriver : public GDALMajorObject
    1949             : {
    1950             :   public:
    1951             :     GDALDriver();
    1952             :     ~GDALDriver() override;
    1953             : 
    1954             :     CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
    1955             :                            const char *pszDomain = "") override;
    1956             : 
    1957             :     /* -------------------------------------------------------------------- */
    1958             :     /*      Public C++ methods.                                             */
    1959             :     /* -------------------------------------------------------------------- */
    1960             :     GDALDataset *Create(const char *pszName, int nXSize, int nYSize, int nBands,
    1961             :                         GDALDataType eType,
    1962             :                         CSLConstList papszOptions) CPL_WARN_UNUSED_RESULT;
    1963             : 
    1964             :     GDALDataset *
    1965             :     CreateMultiDimensional(const char *pszName,
    1966             :                            CSLConstList papszRootGroupOptions,
    1967             :                            CSLConstList papszOptions) CPL_WARN_UNUSED_RESULT;
    1968             : 
    1969             :     CPLErr Delete(const char *pszName);
    1970             :     CPLErr Rename(const char *pszNewName, const char *pszOldName);
    1971             :     CPLErr CopyFiles(const char *pszNewName, const char *pszOldName);
    1972             : 
    1973             :     GDALDataset *CreateCopy(const char *, GDALDataset *, int,
    1974             :                             CSLConstList papszOptions,
    1975             :                             GDALProgressFunc pfnProgress,
    1976             :                             void *pProgressData) CPL_WARN_UNUSED_RESULT;
    1977             : 
    1978             :     bool CanVectorTranslateFrom(const char *pszDestName,
    1979             :                                 GDALDataset *poSourceDS,
    1980             :                                 CSLConstList papszVectorTranslateArguments,
    1981             :                                 char ***ppapszFailureReasons);
    1982             : 
    1983             :     GDALDataset *
    1984             :     VectorTranslateFrom(const char *pszDestName, GDALDataset *poSourceDS,
    1985             :                         CSLConstList papszVectorTranslateArguments,
    1986             :                         GDALProgressFunc pfnProgress,
    1987             :                         void *pProgressData) CPL_WARN_UNUSED_RESULT;
    1988             : 
    1989             :     /* -------------------------------------------------------------------- */
    1990             :     /*      The following are semiprivate, not intended to be accessed      */
    1991             :     /*      by anyone but the formats instantiating and populating the      */
    1992             :     /*      drivers.                                                        */
    1993             :     /* -------------------------------------------------------------------- */
    1994             :     //! @cond Doxygen_Suppress
    1995             : 
    1996             :     // Not aimed at being used outside of GDAL. Use GDALDataset::Open() instead
    1997             :     GDALDataset *Open(GDALOpenInfo *poOpenInfo, bool bSetOpenOptions);
    1998             : 
    1999             :     typedef GDALDataset *(*OpenCallback)(GDALOpenInfo *);
    2000             : 
    2001             :     OpenCallback pfnOpen = nullptr;
    2002             : 
    2003      510531 :     virtual OpenCallback GetOpenCallback()
    2004             :     {
    2005      510531 :         return pfnOpen;
    2006             :     }
    2007             : 
    2008             :     typedef GDALDataset *(*CreateCallback)(const char *pszName, int nXSize,
    2009             :                                            int nYSize, int nBands,
    2010             :                                            GDALDataType eType,
    2011             :                                            char **papszOptions);
    2012             : 
    2013             :     CreateCallback pfnCreate = nullptr;
    2014             : 
    2015       18518 :     virtual CreateCallback GetCreateCallback()
    2016             :     {
    2017       18518 :         return pfnCreate;
    2018             :     }
    2019             : 
    2020             :     GDALDataset *(*pfnCreateEx)(GDALDriver *, const char *pszName, int nXSize,
    2021             :                                 int nYSize, int nBands, GDALDataType eType,
    2022             :                                 char **papszOptions) = nullptr;
    2023             : 
    2024             :     typedef GDALDataset *(*CreateMultiDimensionalCallback)(
    2025             :         const char *pszName, CSLConstList papszRootGroupOptions,
    2026             :         CSLConstList papszOptions);
    2027             : 
    2028             :     CreateMultiDimensionalCallback pfnCreateMultiDimensional = nullptr;
    2029             : 
    2030         461 :     virtual CreateMultiDimensionalCallback GetCreateMultiDimensionalCallback()
    2031             :     {
    2032         461 :         return pfnCreateMultiDimensional;
    2033             :     }
    2034             : 
    2035             :     typedef CPLErr (*DeleteCallback)(const char *pszName);
    2036             :     DeleteCallback pfnDelete = nullptr;
    2037             : 
    2038        5466 :     virtual DeleteCallback GetDeleteCallback()
    2039             :     {
    2040        5466 :         return pfnDelete;
    2041             :     }
    2042             : 
    2043             :     typedef GDALDataset *(*CreateCopyCallback)(const char *, GDALDataset *, int,
    2044             :                                                char **,
    2045             :                                                GDALProgressFunc pfnProgress,
    2046             :                                                void *pProgressData);
    2047             : 
    2048             :     CreateCopyCallback pfnCreateCopy = nullptr;
    2049             : 
    2050        9902 :     virtual CreateCopyCallback GetCreateCopyCallback()
    2051             :     {
    2052        9902 :         return pfnCreateCopy;
    2053             :     }
    2054             : 
    2055             :     void *pDriverData = nullptr;
    2056             : 
    2057             :     void (*pfnUnloadDriver)(GDALDriver *) = nullptr;
    2058             : 
    2059             :     /** Identify() if the file is recognized or not by the driver.
    2060             : 
    2061             :        Return GDAL_IDENTIFY_TRUE (1) if the passed file is certainly recognized
    2062             :        by the driver. Return GDAL_IDENTIFY_FALSE (0) if the passed file is
    2063             :        certainly NOT recognized by the driver. Return GDAL_IDENTIFY_UNKNOWN (-1)
    2064             :        if the passed file may be or may not be recognized by the driver, and
    2065             :        that a potentially costly test must be done with pfnOpen.
    2066             :     */
    2067             :     int (*pfnIdentify)(GDALOpenInfo *) = nullptr;
    2068             :     int (*pfnIdentifyEx)(GDALDriver *, GDALOpenInfo *) = nullptr;
    2069             : 
    2070             :     typedef CPLErr (*RenameCallback)(const char *pszNewName,
    2071             :                                      const char *pszOldName);
    2072             :     RenameCallback pfnRename = nullptr;
    2073             : 
    2074         173 :     virtual RenameCallback GetRenameCallback()
    2075             :     {
    2076         173 :         return pfnRename;
    2077             :     }
    2078             : 
    2079             :     typedef CPLErr (*CopyFilesCallback)(const char *pszNewName,
    2080             :                                         const char *pszOldName);
    2081             :     CopyFilesCallback pfnCopyFiles = nullptr;
    2082             : 
    2083           3 :     virtual CopyFilesCallback GetCopyFilesCallback()
    2084             :     {
    2085           3 :         return pfnCopyFiles;
    2086             :     }
    2087             : 
    2088             :     // Used for legacy OGR drivers, and Python drivers
    2089             :     GDALDataset *(*pfnOpenWithDriverArg)(GDALDriver *,
    2090             :                                          GDALOpenInfo *) = nullptr;
    2091             : 
    2092             :     /* For legacy OGR drivers */
    2093             :     GDALDataset *(*pfnCreateVectorOnly)(GDALDriver *, const char *pszName,
    2094             :                                         char **papszOptions) = nullptr;
    2095             :     CPLErr (*pfnDeleteDataSource)(GDALDriver *, const char *pszName) = nullptr;
    2096             : 
    2097             :     /** Whether pfnVectorTranslateFrom() can be run given the source dataset
    2098             :      * and the non-positional arguments of GDALVectorTranslate() stored
    2099             :      * in papszVectorTranslateArguments.
    2100             :      */
    2101             :     bool (*pfnCanVectorTranslateFrom)(
    2102             :         const char *pszDestName, GDALDataset *poSourceDS,
    2103             :         CSLConstList papszVectorTranslateArguments,
    2104             :         char ***ppapszFailureReasons) = nullptr;
    2105             : 
    2106             :     /** Creates a copy from the specified source dataset, using the
    2107             :      * non-positional arguments of GDALVectorTranslate() stored
    2108             :      * in papszVectorTranslateArguments.
    2109             :      */
    2110             :     GDALDataset *(*pfnVectorTranslateFrom)(
    2111             :         const char *pszDestName, GDALDataset *poSourceDS,
    2112             :         CSLConstList papszVectorTranslateArguments,
    2113             :         GDALProgressFunc pfnProgress, void *pProgressData) = nullptr;
    2114             : 
    2115             :     /**
    2116             :      * Returns a (possibly null) pointer to the Subdataset informational function
    2117             :      * from the subdataset file name.
    2118             :      */
    2119             :     GDALSubdatasetInfo *(*pfnGetSubdatasetInfoFunc)(const char *pszFileName) =
    2120             :         nullptr;
    2121             : 
    2122             :     //! @endcond
    2123             : 
    2124             :     /* -------------------------------------------------------------------- */
    2125             :     /*      Helper methods.                                                 */
    2126             :     /* -------------------------------------------------------------------- */
    2127             :     //! @cond Doxygen_Suppress
    2128             :     GDALDataset *DefaultCreateCopy(const char *, GDALDataset *, int,
    2129             :                                    CSLConstList papszOptions,
    2130             :                                    GDALProgressFunc pfnProgress,
    2131             :                                    void *pProgressData) CPL_WARN_UNUSED_RESULT;
    2132             : 
    2133             :     static CPLErr DefaultCreateCopyMultiDimensional(
    2134             :         GDALDataset *poSrcDS, GDALDataset *poDstDS, bool bStrict,
    2135             :         CSLConstList /*papszOptions*/, GDALProgressFunc pfnProgress,
    2136             :         void *pProgressData);
    2137             : 
    2138             :     static CPLErr DefaultCopyMasks(GDALDataset *poSrcDS, GDALDataset *poDstDS,
    2139             :                                    int bStrict);
    2140             :     static CPLErr DefaultCopyMasks(GDALDataset *poSrcDS, GDALDataset *poDstDS,
    2141             :                                    int bStrict, CSLConstList papszOptions,
    2142             :                                    GDALProgressFunc pfnProgress,
    2143             :                                    void *pProgressData);
    2144             : 
    2145             :     CPLErr QuietDeleteForCreateCopy(const char *pszFilename,
    2146             :                                     GDALDataset *poSrcDS);
    2147             : 
    2148             :     //! @endcond
    2149             :     static CPLErr QuietDelete(const char *pszName,
    2150             :                               CSLConstList papszAllowedDrivers = nullptr);
    2151             : 
    2152             :     //! @cond Doxygen_Suppress
    2153             :     static CPLErr DefaultRename(const char *pszNewName, const char *pszOldName);
    2154             :     static CPLErr DefaultCopyFiles(const char *pszNewName,
    2155             :                                    const char *pszOldName);
    2156             :     static void DefaultCopyMetadata(GDALDataset *poSrcDS, GDALDataset *poDstDS,
    2157             :                                     CSLConstList papszOptions,
    2158             :                                     CSLConstList papszExcludedDomains);
    2159             : 
    2160             :     //! @endcond
    2161             : 
    2162             :     /** Convert a GDALDriver* to a GDALDriverH.
    2163             :      * @since GDAL 2.3
    2164             :      */
    2165          20 :     static inline GDALDriverH ToHandle(GDALDriver *poDriver)
    2166             :     {
    2167          20 :         return static_cast<GDALDriverH>(poDriver);
    2168             :     }
    2169             : 
    2170             :     /** Convert a GDALDriverH to a GDALDriver*.
    2171             :      * @since GDAL 2.3
    2172             :      */
    2173     3501393 :     static inline GDALDriver *FromHandle(GDALDriverH hDriver)
    2174             :     {
    2175     3501393 :         return static_cast<GDALDriver *>(hDriver);
    2176             :     }
    2177             : 
    2178             :   private:
    2179             :     CPL_DISALLOW_COPY_ASSIGN(GDALDriver)
    2180             : };
    2181             : 
    2182             : /************************************************************************/
    2183             : /*                       GDALPluginDriverProxy                          */
    2184             : /************************************************************************/
    2185             : 
    2186             : // clang-format off
    2187             : /** Proxy for a plugin driver.
    2188             :  *
    2189             :  * Such proxy must be registered with
    2190             :  * GDALDriverManager::DeclareDeferredPluginDriver().
    2191             :  *
    2192             :  * If the real driver defines any of the following metadata items, the
    2193             :  * proxy driver should also define them with the same value:
    2194             :  * <ul>
    2195             :  * <li>GDAL_DMD_LONGNAME</li>
    2196             :  * <li>GDAL_DMD_EXTENSIONS</li>
    2197             :  * <li>GDAL_DMD_EXTENSION</li>
    2198             :  * <li>GDAL_DMD_OPENOPTIONLIST</li>
    2199             :  * <li>GDAL_DMD_SUBDATASETS</li>
    2200             :  * <li>GDAL_DMD_CONNECTION_PREFIX</li>
    2201             :  * <li>GDAL_DCAP_RASTER</li>
    2202             :  * <li>GDAL_DCAP_MULTIDIM_RASTER</li>
    2203             :  * <li>GDAL_DCAP_VECTOR</li>
    2204             :  * <li>GDAL_DCAP_GNM</li>
    2205             :  * <li>GDAL_DCAP_MULTIPLE_VECTOR_LAYERS</li>
    2206             :  * <li>GDAL_DCAP_NONSPATIAL</li>
    2207             :  * <li>GDAL_DCAP_VECTOR_TRANSLATE_FROM</li>
    2208             :  * </ul>
    2209             :  *
    2210             :  * The pfnIdentify and pfnGetSubdatasetInfoFunc callbacks, if they are
    2211             :  * defined in the real driver, should also be set on the proxy driver.
    2212             :  *
    2213             :  * Furthermore, the following metadata items must be defined if the real
    2214             :  * driver sets the corresponding callback:
    2215             :  * <ul>
    2216             :  * <li>GDAL_DCAP_OPEN: must be set to YES if the real driver defines pfnOpen</li>
    2217             :  * <li>GDAL_DCAP_CREATE: must be set to YES if the real driver defines pfnCreate</li>
    2218             :  * <li>GDAL_DCAP_CREATE_MULTIDIMENSIONAL: must be set to YES if the real driver defines pfnCreateMultiDimensional</li>
    2219             :  * <li>GDAL_DCAP_CREATECOPY: must be set to YES if the real driver defines pfnCreateCopy</li>
    2220             :  * </ul>
    2221             :  *
    2222             :  * @since 3.9
    2223             :  */
    2224             : // clang-format on
    2225             : class GDALPluginDriverProxy : public GDALDriver
    2226             : {
    2227             :     const std::string m_osPluginFileName;
    2228             :     std::string m_osPluginFullPath{};
    2229             :     std::unique_ptr<GDALDriver> m_poRealDriver{};
    2230             :     std::set<std::string> m_oSetMetadataItems{};
    2231             : 
    2232             :     GDALDriver *GetRealDriver();
    2233             : 
    2234             :     CPL_DISALLOW_COPY_ASSIGN(GDALPluginDriverProxy)
    2235             : 
    2236             :   protected:
    2237             :     friend class GDALDriverManager;
    2238             : 
    2239             :     //! @cond Doxygen_Suppress
    2240       52417 :     void SetPluginFullPath(const std::string &osFullPath)
    2241             :     {
    2242       52417 :         m_osPluginFullPath = osFullPath;
    2243       52417 :     }
    2244             : 
    2245             :     //! @endcond
    2246             : 
    2247             :   public:
    2248             :     explicit GDALPluginDriverProxy(const std::string &osPluginFileName);
    2249             : 
    2250             :     /** Return the plugin file name (not a full path) */
    2251       52417 :     const std::string &GetPluginFileName() const
    2252             :     {
    2253       52417 :         return m_osPluginFileName;
    2254             :     }
    2255             : 
    2256             :     //! @cond Doxygen_Suppress
    2257             :     OpenCallback GetOpenCallback() override;
    2258             : 
    2259             :     CreateCallback GetCreateCallback() override;
    2260             : 
    2261             :     CreateMultiDimensionalCallback GetCreateMultiDimensionalCallback() override;
    2262             : 
    2263             :     CreateCopyCallback GetCreateCopyCallback() override;
    2264             : 
    2265             :     DeleteCallback GetDeleteCallback() override;
    2266             : 
    2267             :     RenameCallback GetRenameCallback() override;
    2268             : 
    2269             :     CopyFilesCallback GetCopyFilesCallback() override;
    2270             :     //! @endcond
    2271             : 
    2272             :     CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
    2273             :                            const char *pszDomain = "") override;
    2274             : 
    2275             :     char **GetMetadata(const char *pszDomain) override;
    2276             : 
    2277             :     const char *GetMetadataItem(const char *pszName,
    2278             :                                 const char *pszDomain = "") override;
    2279             : };
    2280             : 
    2281             : /* ******************************************************************** */
    2282             : /*                          GDALDriverManager                           */
    2283             : /* ******************************************************************** */
    2284             : 
    2285             : /**
    2286             :  * Class for managing the registration of file format drivers.
    2287             :  *
    2288             :  * Use GetGDALDriverManager() to fetch the global singleton instance of
    2289             :  * this class.
    2290             :  */
    2291             : 
    2292             : class CPL_DLL GDALDriverManager : public GDALMajorObject
    2293             : {
    2294             :     int nDrivers = 0;
    2295             :     GDALDriver **papoDrivers = nullptr;
    2296             :     std::map<CPLString, GDALDriver *> oMapNameToDrivers{};
    2297             :     std::string m_osPluginPath{};
    2298             :     std::string m_osDriversIniPath{};
    2299             :     mutable std::string m_osLastTriedDirectory{};
    2300             :     std::set<std::string> m_oSetPluginFileNames{};
    2301             :     bool m_bInDeferredDriverLoading = false;
    2302             :     std::map<std::string, std::unique_ptr<GDALDriver>> m_oMapRealDrivers{};
    2303             :     std::vector<std::unique_ptr<GDALDriver>> m_aoHiddenDrivers{};
    2304             : 
    2305    17411800 :     GDALDriver *GetDriver_unlocked(int iDriver)
    2306             :     {
    2307    17411800 :         return (iDriver >= 0 && iDriver < nDrivers) ? papoDrivers[iDriver]
    2308    17411800 :                                                     : nullptr;
    2309             :     }
    2310             : 
    2311      720389 :     GDALDriver *GetDriverByName_unlocked(const char *pszName) const
    2312             :     {
    2313      720389 :         auto oIter = oMapNameToDrivers.find(CPLString(pszName).toupper());
    2314      720389 :         return oIter == oMapNameToDrivers.end() ? nullptr : oIter->second;
    2315             :     }
    2316             : 
    2317             :     static void CleanupPythonDrivers();
    2318             : 
    2319             :     std::string GetPluginFullPath(const char *pszFilename) const;
    2320             : 
    2321             :     int RegisterDriver(GDALDriver *, bool bHidden);
    2322             : 
    2323             :     CPL_DISALLOW_COPY_ASSIGN(GDALDriverManager)
    2324             : 
    2325             :   protected:
    2326             :     friend class GDALPluginDriverProxy;
    2327             :     friend GDALDatasetH CPL_STDCALL
    2328             :     GDALOpenEx(const char *pszFilename, unsigned int nOpenFlags,
    2329             :                const char *const *papszAllowedDrivers,
    2330             :                const char *const *papszOpenOptions,
    2331             :                const char *const *papszSiblingFiles);
    2332             : 
    2333             :     //! @cond Doxygen_Suppress
    2334             :     static char **GetSearchPaths(const char *pszGDAL_DRIVER_PATH);
    2335             :     int GetDriverCount(bool bIncludeHidden) const;
    2336             :     GDALDriver *GetDriver(int iDriver, bool bIncludeHidden);
    2337             :     //! @endcond
    2338             : 
    2339             :   public:
    2340             :     GDALDriverManager();
    2341             :     ~GDALDriverManager();
    2342             : 
    2343             :     int GetDriverCount(void) const;
    2344             :     GDALDriver *GetDriver(int);
    2345             :     GDALDriver *GetDriverByName(const char *);
    2346             : 
    2347             :     int RegisterDriver(GDALDriver *);
    2348             :     void DeregisterDriver(GDALDriver *);
    2349             : 
    2350             :     // AutoLoadDrivers is a no-op if compiled with GDAL_NO_AUTOLOAD defined.
    2351             :     void AutoLoadDrivers();
    2352             :     void AutoSkipDrivers();
    2353             :     void ReorderDrivers();
    2354             :     static CPLErr LoadPlugin(const char *name);
    2355             : 
    2356             :     static void AutoLoadPythonDrivers();
    2357             : 
    2358             :     void DeclareDeferredPluginDriver(GDALPluginDriverProxy *poProxyDriver);
    2359             : };
    2360             : 
    2361             : CPL_C_START
    2362             : GDALDriverManager CPL_DLL *GetGDALDriverManager(void);
    2363             : CPL_C_END
    2364             : 
    2365             : /* ******************************************************************** */
    2366             : /*                          GDALAsyncReader                             */
    2367             : /* ******************************************************************** */
    2368             : 
    2369             : /**
    2370             :  * Class used as a session object for asynchronous requests.  They are
    2371             :  * created with GDALDataset::BeginAsyncReader(), and destroyed with
    2372             :  * GDALDataset::EndAsyncReader().
    2373             :  */
    2374           1 : class CPL_DLL GDALAsyncReader
    2375             : {
    2376             : 
    2377             :     CPL_DISALLOW_COPY_ASSIGN(GDALAsyncReader)
    2378             : 
    2379             :   protected:
    2380             :     //! @cond Doxygen_Suppress
    2381             :     GDALDataset *poDS;
    2382             :     int nXOff;
    2383             :     int nYOff;
    2384             :     int nXSize;
    2385             :     int nYSize;
    2386             :     void *pBuf;
    2387             :     int nBufXSize;
    2388             :     int nBufYSize;
    2389             :     GDALDataType eBufType;
    2390             :     int nBandCount;
    2391             :     int *panBandMap;
    2392             :     int nPixelSpace;
    2393             :     int nLineSpace;
    2394             :     int nBandSpace;
    2395             :     //! @endcond
    2396             : 
    2397             :   public:
    2398             :     GDALAsyncReader();
    2399             :     virtual ~GDALAsyncReader();
    2400             : 
    2401             :     /** Return dataset.
    2402             :      * @return dataset
    2403             :      */
    2404             :     GDALDataset *GetGDALDataset()
    2405             :     {
    2406             :         return poDS;
    2407             :     }
    2408             : 
    2409             :     /** Return x offset.
    2410             :      * @return x offset.
    2411             :      */
    2412             :     int GetXOffset() const
    2413             :     {
    2414             :         return nXOff;
    2415             :     }
    2416             : 
    2417             :     /** Return y offset.
    2418             :      * @return y offset.
    2419             :      */
    2420             :     int GetYOffset() const
    2421             :     {
    2422             :         return nYOff;
    2423             :     }
    2424             : 
    2425             :     /** Return width.
    2426             :      * @return width
    2427             :      */
    2428             :     int GetXSize() const
    2429             :     {
    2430             :         return nXSize;
    2431             :     }
    2432             : 
    2433             :     /** Return height.
    2434             :      * @return height
    2435             :      */
    2436             :     int GetYSize() const
    2437             :     {
    2438             :         return nYSize;
    2439             :     }
    2440             : 
    2441             :     /** Return buffer.
    2442             :      * @return buffer
    2443             :      */
    2444             :     void *GetBuffer()
    2445             :     {
    2446             :         return pBuf;
    2447             :     }
    2448             : 
    2449             :     /** Return buffer width.
    2450             :      * @return buffer width.
    2451             :      */
    2452             :     int GetBufferXSize() const
    2453             :     {
    2454             :         return nBufXSize;
    2455             :     }
    2456             : 
    2457             :     /** Return buffer height.
    2458             :      * @return buffer height.
    2459             :      */
    2460             :     int GetBufferYSize() const
    2461             :     {
    2462             :         return nBufYSize;
    2463             :     }
    2464             : 
    2465             :     /** Return buffer data type.
    2466             :      * @return buffer data type.
    2467             :      */
    2468             :     GDALDataType GetBufferType() const
    2469             :     {
    2470             :         return eBufType;
    2471             :     }
    2472             : 
    2473             :     /** Return band count.
    2474             :      * @return band count
    2475             :      */
    2476             :     int GetBandCount() const
    2477             :     {
    2478             :         return nBandCount;
    2479             :     }
    2480             : 
    2481             :     /** Return band map.
    2482             :      * @return band map.
    2483             :      */
    2484             :     int *GetBandMap()
    2485             :     {
    2486             :         return panBandMap;
    2487             :     }
    2488             : 
    2489             :     /** Return pixel spacing.
    2490             :      * @return pixel spacing.
    2491             :      */
    2492             :     int GetPixelSpace() const
    2493             :     {
    2494             :         return nPixelSpace;
    2495             :     }
    2496             : 
    2497             :     /** Return line spacing.
    2498             :      * @return line spacing.
    2499             :      */
    2500             :     int GetLineSpace() const
    2501             :     {
    2502             :         return nLineSpace;
    2503             :     }
    2504             : 
    2505             :     /** Return band spacing.
    2506             :      * @return band spacing.
    2507             :      */
    2508             :     int GetBandSpace() const
    2509             :     {
    2510             :         return nBandSpace;
    2511             :     }
    2512             : 
    2513             :     virtual GDALAsyncStatusType
    2514             :     GetNextUpdatedRegion(double dfTimeout, int *pnBufXOff, int *pnBufYOff,
    2515             :                          int *pnBufXSize, int *pnBufYSize) = 0;
    2516             :     virtual int LockBuffer(double dfTimeout = -1.0);
    2517             :     virtual void UnlockBuffer();
    2518             : };
    2519             : 
    2520             : /* ******************************************************************** */
    2521             : /*                       Multidimensional array API                     */
    2522             : /* ******************************************************************** */
    2523             : 
    2524             : class GDALMDArray;
    2525             : class GDALAttribute;
    2526             : class GDALDimension;
    2527             : class GDALEDTComponent;
    2528             : 
    2529             : /* ******************************************************************** */
    2530             : /*                         GDALExtendedDataType                         */
    2531             : /* ******************************************************************** */
    2532             : 
    2533             : /**
    2534             :  * Class used to represent potentially complex data types.
    2535             :  * Several classes of data types are supported: numeric (based on GDALDataType),
    2536             :  * compound or string.
    2537             :  *
    2538             :  * @since GDAL 3.1
    2539             :  */
    2540       53976 : class CPL_DLL GDALExtendedDataType
    2541             : {
    2542             :   public:
    2543             :     ~GDALExtendedDataType();
    2544             : 
    2545             :     GDALExtendedDataType(const GDALExtendedDataType &);
    2546             : 
    2547             :     GDALExtendedDataType &operator=(const GDALExtendedDataType &);
    2548             :     GDALExtendedDataType &operator=(GDALExtendedDataType &&);
    2549             : 
    2550             :     static GDALExtendedDataType Create(GDALDataType eType);
    2551             :     static GDALExtendedDataType
    2552             :     Create(const std::string &osName, size_t nTotalSize,
    2553             :            std::vector<std::unique_ptr<GDALEDTComponent>> &&components);
    2554             :     static GDALExtendedDataType
    2555             :     CreateString(size_t nMaxStringLength = 0,
    2556             :                  GDALExtendedDataTypeSubType eSubType = GEDTST_NONE);
    2557             : 
    2558             :     bool operator==(const GDALExtendedDataType &) const;
    2559             : 
    2560             :     /** Non-equality operator */
    2561         905 :     bool operator!=(const GDALExtendedDataType &other) const
    2562             :     {
    2563         905 :         return !(operator==(other));
    2564             :     }
    2565             : 
    2566             :     /** Return type name.
    2567             :      *
    2568             :      * This is the same as the C function GDALExtendedDataTypeGetName()
    2569             :      */
    2570          18 :     const std::string &GetName() const
    2571             :     {
    2572          18 :         return m_osName;
    2573             :     }
    2574             : 
    2575             :     /** Return type class.
    2576             :      *
    2577             :      * This is the same as the C function GDALExtendedDataTypeGetClass()
    2578             :      */
    2579      285460 :     GDALExtendedDataTypeClass GetClass() const
    2580             :     {
    2581      285460 :         return m_eClass;
    2582             :     }
    2583             : 
    2584             :     /** Return numeric data type (only valid when GetClass() == GEDTC_NUMERIC)
    2585             :      *
    2586             :      * This is the same as the C function
    2587             :      * GDALExtendedDataTypeGetNumericDataType()
    2588             :      */
    2589     1925924 :     GDALDataType GetNumericDataType() const
    2590             :     {
    2591     1925924 :         return m_eNumericDT;
    2592             :     }
    2593             : 
    2594             :     /** Return subtype.
    2595             :      *
    2596             :      * This is the same as the C function GDALExtendedDataTypeGetSubType()
    2597             :      *
    2598             :      * @since 3.4
    2599             :      */
    2600         305 :     GDALExtendedDataTypeSubType GetSubType() const
    2601             :     {
    2602         305 :         return m_eSubType;
    2603             :     }
    2604             : 
    2605             :     /** Return the components of the data type (only valid when GetClass() ==
    2606             :      * GEDTC_COMPOUND)
    2607             :      *
    2608             :      * This is the same as the C function GDALExtendedDataTypeGetComponents()
    2609             :      */
    2610         716 :     const std::vector<std::unique_ptr<GDALEDTComponent>> &GetComponents() const
    2611             :     {
    2612         716 :         return m_aoComponents;
    2613             :     }
    2614             : 
    2615             :     /** Return data type size in bytes.
    2616             :      *
    2617             :      * For a string, this will be size of a char* pointer.
    2618             :      *
    2619             :      * This is the same as the C function GDALExtendedDataTypeGetSize()
    2620             :      */
    2621       48350 :     size_t GetSize() const
    2622             :     {
    2623       48350 :         return m_nSize;
    2624             :     }
    2625             : 
    2626             :     /** Return the maximum length of a string in bytes.
    2627             :      *
    2628             :      * 0 indicates unknown/unlimited string.
    2629             :      */
    2630          21 :     size_t GetMaxStringLength() const
    2631             :     {
    2632          21 :         return m_nMaxStringLength;
    2633             :     }
    2634             : 
    2635             :     bool CanConvertTo(const GDALExtendedDataType &other) const;
    2636             : 
    2637             :     bool NeedsFreeDynamicMemory() const;
    2638             : 
    2639             :     void FreeDynamicMemory(void *pBuffer) const;
    2640             : 
    2641             :     static bool CopyValue(const void *pSrc, const GDALExtendedDataType &srcType,
    2642             :                           void *pDst, const GDALExtendedDataType &dstType);
    2643             : 
    2644             :     static bool CopyValues(const void *pSrc,
    2645             :                            const GDALExtendedDataType &srcType,
    2646             :                            GPtrDiff_t nSrcStrideInElts, void *pDst,
    2647             :                            const GDALExtendedDataType &dstType,
    2648             :                            GPtrDiff_t nDstStrideInElts, size_t nValues);
    2649             : 
    2650             :   private:
    2651             :     GDALExtendedDataType(size_t nMaxStringLength,
    2652             :                          GDALExtendedDataTypeSubType eSubType);
    2653             :     explicit GDALExtendedDataType(GDALDataType eType);
    2654             :     GDALExtendedDataType(
    2655             :         const std::string &osName, size_t nTotalSize,
    2656             :         std::vector<std::unique_ptr<GDALEDTComponent>> &&components);
    2657             : 
    2658             :     std::string m_osName{};
    2659             :     GDALExtendedDataTypeClass m_eClass = GEDTC_NUMERIC;
    2660             :     GDALExtendedDataTypeSubType m_eSubType = GEDTST_NONE;
    2661             :     GDALDataType m_eNumericDT = GDT_Unknown;
    2662             :     std::vector<std::unique_ptr<GDALEDTComponent>> m_aoComponents{};
    2663             :     size_t m_nSize = 0;
    2664             :     size_t m_nMaxStringLength = 0;
    2665             : };
    2666             : 
    2667             : /* ******************************************************************** */
    2668             : /*                            GDALEDTComponent                          */
    2669             : /* ******************************************************************** */
    2670             : 
    2671             : /**
    2672             :  * Class for a component of a compound extended data type.
    2673             :  *
    2674             :  * @since GDAL 3.1
    2675             :  */
    2676        3217 : class CPL_DLL GDALEDTComponent
    2677             : {
    2678             :   public:
    2679             :     ~GDALEDTComponent();
    2680             :     GDALEDTComponent(const std::string &name, size_t offset,
    2681             :                      const GDALExtendedDataType &type);
    2682             :     GDALEDTComponent(const GDALEDTComponent &);
    2683             : 
    2684             :     bool operator==(const GDALEDTComponent &) const;
    2685             : 
    2686             :     /** Return the name.
    2687             :      *
    2688             :      * This is the same as the C function GDALEDTComponentGetName().
    2689             :      */
    2690        2104 :     const std::string &GetName() const
    2691             :     {
    2692        2104 :         return m_osName;
    2693             :     }
    2694             : 
    2695             :     /** Return the offset (in bytes) of the component in the compound data type.
    2696             :      *
    2697             :      * This is the same as the C function GDALEDTComponentGetOffset().
    2698             :      */
    2699        6191 :     size_t GetOffset() const
    2700             :     {
    2701        6191 :         return m_nOffset;
    2702             :     }
    2703             : 
    2704             :     /** Return the data type of the component.
    2705             :      *
    2706             :      * This is the same as the C function GDALEDTComponentGetType().
    2707             :      */
    2708        5845 :     const GDALExtendedDataType &GetType() const
    2709             :     {
    2710        5845 :         return m_oType;
    2711             :     }
    2712             : 
    2713             :   private:
    2714             :     std::string m_osName;
    2715             :     size_t m_nOffset;
    2716             :     GDALExtendedDataType m_oType;
    2717             : };
    2718             : 
    2719             : /* ******************************************************************** */
    2720             : /*                            GDALIHasAttribute                         */
    2721             : /* ******************************************************************** */
    2722             : 
    2723             : /**
    2724             :  * Interface used to get a single GDALAttribute or a set of GDALAttribute
    2725             :  *
    2726             :  * @since GDAL 3.1
    2727             :  */
    2728       12451 : class CPL_DLL GDALIHasAttribute
    2729             : {
    2730             :   protected:
    2731             :     std::shared_ptr<GDALAttribute>
    2732             :     GetAttributeFromAttributes(const std::string &osName) const;
    2733             : 
    2734             :   public:
    2735             :     virtual ~GDALIHasAttribute();
    2736             : 
    2737             :     virtual std::shared_ptr<GDALAttribute>
    2738             :     GetAttribute(const std::string &osName) const;
    2739             : 
    2740             :     virtual std::vector<std::shared_ptr<GDALAttribute>>
    2741             :     GetAttributes(CSLConstList papszOptions = nullptr) const;
    2742             : 
    2743             :     virtual std::shared_ptr<GDALAttribute>
    2744             :     CreateAttribute(const std::string &osName,
    2745             :                     const std::vector<GUInt64> &anDimensions,
    2746             :                     const GDALExtendedDataType &oDataType,
    2747             :                     CSLConstList papszOptions = nullptr);
    2748             : 
    2749             :     virtual bool DeleteAttribute(const std::string &osName,
    2750             :                                  CSLConstList papszOptions = nullptr);
    2751             : };
    2752             : 
    2753             : /* ******************************************************************** */
    2754             : /*                               GDALGroup                              */
    2755             : /* ******************************************************************** */
    2756             : 
    2757             : /* clang-format off */
    2758             : /**
    2759             :  * Class modeling a named container of GDALAttribute, GDALMDArray, OGRLayer or
    2760             :  * other GDALGroup. Hence GDALGroup can describe a hierarchy of objects.
    2761             :  *
    2762             :  * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_group">HDF5 group
    2763             :  * concept</a>
    2764             :  *
    2765             :  * @since GDAL 3.1
    2766             :  */
    2767             : /* clang-format on */
    2768             : 
    2769        6447 : class CPL_DLL GDALGroup : public GDALIHasAttribute
    2770             : {
    2771             :   protected:
    2772             :     //! @cond Doxygen_Suppress
    2773             :     std::string m_osName{};
    2774             : 
    2775             :     // This is actually a path of the form "/parent_path/{m_osName}"
    2776             :     std::string m_osFullName{};
    2777             : 
    2778             :     // Used for example by GDALSubsetGroup to distinguish a derived group
    2779             :     //from its original, without altering its name
    2780             :     const std::string m_osContext{};
    2781             : 
    2782             :     std::weak_ptr<GDALGroup> m_pSelf{};
    2783             : 
    2784             :     //! Can be set to false by the owing group, when deleting this object
    2785             :     bool m_bValid = true;
    2786             : 
    2787             :     GDALGroup(const std::string &osParentName, const std::string &osName,
    2788             :               const std::string &osContext = std::string());
    2789             : 
    2790             :     const GDALGroup *
    2791             :     GetInnerMostGroup(const std::string &osPathOrArrayOrDim,
    2792             :                       std::shared_ptr<GDALGroup> &curGroupHolder,
    2793             :                       std::string &osLastPart) const;
    2794             : 
    2795             :     void BaseRename(const std::string &osNewName);
    2796             : 
    2797             :     bool CheckValidAndErrorOutIfNot() const;
    2798             : 
    2799        5553 :     void SetSelf(const std::shared_ptr<GDALGroup> &self)
    2800             :     {
    2801        5553 :         m_pSelf = self;
    2802        5553 :     }
    2803             : 
    2804           0 :     virtual void NotifyChildrenOfRenaming()
    2805             :     {
    2806           0 :     }
    2807             : 
    2808           0 :     virtual void NotifyChildrenOfDeletion()
    2809             :     {
    2810           0 :     }
    2811             : 
    2812             :     //! @endcond
    2813             : 
    2814             :   public:
    2815             :     virtual ~GDALGroup();
    2816             : 
    2817             :     /** Return the name of the group.
    2818             :      *
    2819             :      * This is the same as the C function GDALGroupGetName().
    2820             :      */
    2821         944 :     const std::string &GetName() const
    2822             :     {
    2823         944 :         return m_osName;
    2824             :     }
    2825             : 
    2826             :     /** Return the full name of the group.
    2827             :      *
    2828             :      * This is the same as the C function GDALGroupGetFullName().
    2829             :      */
    2830       18966 :     const std::string &GetFullName() const
    2831             :     {
    2832       18966 :         return m_osFullName;
    2833             :     }
    2834             : 
    2835             :     virtual std::vector<std::string>
    2836             :     GetMDArrayNames(CSLConstList papszOptions = nullptr) const;
    2837             :     virtual std::shared_ptr<GDALMDArray>
    2838             :     OpenMDArray(const std::string &osName,
    2839             :                 CSLConstList papszOptions = nullptr) const;
    2840             : 
    2841             :     virtual std::vector<std::string>
    2842             :     GetGroupNames(CSLConstList papszOptions = nullptr) const;
    2843             :     virtual std::shared_ptr<GDALGroup>
    2844             :     OpenGroup(const std::string &osName,
    2845             :               CSLConstList papszOptions = nullptr) const;
    2846             : 
    2847             :     virtual std::vector<std::string>
    2848             :     GetVectorLayerNames(CSLConstList papszOptions = nullptr) const;
    2849             :     virtual OGRLayer *
    2850             :     OpenVectorLayer(const std::string &osName,
    2851             :                     CSLConstList papszOptions = nullptr) const;
    2852             : 
    2853             :     virtual std::vector<std::shared_ptr<GDALDimension>>
    2854             :     GetDimensions(CSLConstList papszOptions = nullptr) const;
    2855             : 
    2856             :     virtual std::shared_ptr<GDALGroup>
    2857             :     CreateGroup(const std::string &osName, CSLConstList papszOptions = nullptr);
    2858             : 
    2859             :     virtual bool DeleteGroup(const std::string &osName,
    2860             :                              CSLConstList papszOptions = nullptr);
    2861             : 
    2862             :     virtual std::shared_ptr<GDALDimension>
    2863             :     CreateDimension(const std::string &osName, const std::string &osType,
    2864             :                     const std::string &osDirection, GUInt64 nSize,
    2865             :                     CSLConstList papszOptions = nullptr);
    2866             : 
    2867             :     virtual std::shared_ptr<GDALMDArray> CreateMDArray(
    2868             :         const std::string &osName,
    2869             :         const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
    2870             :         const GDALExtendedDataType &oDataType,
    2871             :         CSLConstList papszOptions = nullptr);
    2872             : 
    2873             :     virtual bool DeleteMDArray(const std::string &osName,
    2874             :                                CSLConstList papszOptions = nullptr);
    2875             : 
    2876             :     GUInt64 GetTotalCopyCost() const;
    2877             : 
    2878             :     virtual bool CopyFrom(const std::shared_ptr<GDALGroup> &poDstRootGroup,
    2879             :                           GDALDataset *poSrcDS,
    2880             :                           const std::shared_ptr<GDALGroup> &poSrcGroup,
    2881             :                           bool bStrict, GUInt64 &nCurCost,
    2882             :                           const GUInt64 nTotalCost,
    2883             :                           GDALProgressFunc pfnProgress, void *pProgressData,
    2884             :                           CSLConstList papszOptions = nullptr);
    2885             : 
    2886             :     virtual CSLConstList GetStructuralInfo() const;
    2887             : 
    2888             :     std::shared_ptr<GDALMDArray>
    2889             :     OpenMDArrayFromFullname(const std::string &osFullName,
    2890             :                             CSLConstList papszOptions = nullptr) const;
    2891             : 
    2892             :     std::shared_ptr<GDALMDArray>
    2893             :     ResolveMDArray(const std::string &osName, const std::string &osStartingPath,
    2894             :                    CSLConstList papszOptions = nullptr) const;
    2895             : 
    2896             :     std::shared_ptr<GDALGroup>
    2897             :     OpenGroupFromFullname(const std::string &osFullName,
    2898             :                           CSLConstList papszOptions = nullptr) const;
    2899             : 
    2900             :     std::shared_ptr<GDALDimension>
    2901             :     OpenDimensionFromFullname(const std::string &osFullName) const;
    2902             : 
    2903             :     virtual void ClearStatistics();
    2904             : 
    2905             :     virtual bool Rename(const std::string &osNewName);
    2906             : 
    2907             :     std::shared_ptr<GDALGroup>
    2908             :     SubsetDimensionFromSelection(const std::string &osSelection) const;
    2909             : 
    2910             :     //! @cond Doxygen_Suppress
    2911             :     virtual void ParentRenamed(const std::string &osNewParentFullName);
    2912             : 
    2913             :     virtual void Deleted();
    2914             : 
    2915             :     virtual void ParentDeleted();
    2916             : 
    2917          23 :     const std::string &GetContext() const
    2918             :     {
    2919          23 :         return m_osContext;
    2920             :     }
    2921             : 
    2922             :     //! @endcond
    2923             : 
    2924             :     //! @cond Doxygen_Suppress
    2925             :     static constexpr GUInt64 COPY_COST = 1000;
    2926             :     //! @endcond
    2927             : };
    2928             : 
    2929             : /* ******************************************************************** */
    2930             : /*                          GDALAbstractMDArray                         */
    2931             : /* ******************************************************************** */
    2932             : 
    2933             : /**
    2934             :  * Abstract class, implemented by GDALAttribute and GDALMDArray.
    2935             :  *
    2936             :  * @since GDAL 3.1
    2937             :  */
    2938       17867 : class CPL_DLL GDALAbstractMDArray
    2939             : {
    2940             :   protected:
    2941             :     //! @cond Doxygen_Suppress
    2942             :     std::string m_osName{};
    2943             : 
    2944             :     // This is actually a path of the form "/parent_path/{m_osName}"
    2945             :     std::string m_osFullName{};
    2946             :     std::weak_ptr<GDALAbstractMDArray> m_pSelf{};
    2947             : 
    2948             :     //! Can be set to false by the owing object, when deleting this object
    2949             :     bool m_bValid = true;
    2950             : 
    2951             :     GDALAbstractMDArray(const std::string &osParentName,
    2952             :                         const std::string &osName);
    2953             : 
    2954        7591 :     void SetSelf(const std::shared_ptr<GDALAbstractMDArray> &self)
    2955             :     {
    2956        7591 :         m_pSelf = self;
    2957        7591 :     }
    2958             : 
    2959             :     bool CheckValidAndErrorOutIfNot() const;
    2960             : 
    2961             :     bool CheckReadWriteParams(const GUInt64 *arrayStartIdx, const size_t *count,
    2962             :                               const GInt64 *&arrayStep,
    2963             :                               const GPtrDiff_t *&bufferStride,
    2964             :                               const GDALExtendedDataType &bufferDataType,
    2965             :                               const void *buffer,
    2966             :                               const void *buffer_alloc_start,
    2967             :                               size_t buffer_alloc_size,
    2968             :                               std::vector<GInt64> &tmp_arrayStep,
    2969             :                               std::vector<GPtrDiff_t> &tmp_bufferStride) const;
    2970             : 
    2971             :     virtual bool
    2972             :     IRead(const GUInt64 *arrayStartIdx,    // array of size GetDimensionCount()
    2973             :           const size_t *count,             // array of size GetDimensionCount()
    2974             :           const GInt64 *arrayStep,         // step in elements
    2975             :           const GPtrDiff_t *bufferStride,  // stride in elements
    2976             :           const GDALExtendedDataType &bufferDataType,
    2977             :           void *pDstBuffer) const = 0;
    2978             : 
    2979             :     virtual bool
    2980             :     IWrite(const GUInt64 *arrayStartIdx,    // array of size GetDimensionCount()
    2981             :            const size_t *count,             // array of size GetDimensionCount()
    2982             :            const GInt64 *arrayStep,         // step in elements
    2983             :            const GPtrDiff_t *bufferStride,  // stride in elements
    2984             :            const GDALExtendedDataType &bufferDataType, const void *pSrcBuffer);
    2985             : 
    2986             :     void BaseRename(const std::string &osNewName);
    2987             : 
    2988          47 :     virtual void NotifyChildrenOfRenaming()
    2989             :     {
    2990          47 :     }
    2991             : 
    2992          42 :     virtual void NotifyChildrenOfDeletion()
    2993             :     {
    2994          42 :     }
    2995             : 
    2996             :     //! @endcond
    2997             : 
    2998             :   public:
    2999             :     virtual ~GDALAbstractMDArray();
    3000             : 
    3001             :     /** Return the name of an array or attribute.
    3002             :      *
    3003             :      * This is the same as the C function GDALMDArrayGetName() or
    3004             :      * GDALAttributeGetName().
    3005             :      */
    3006       16375 :     const std::string &GetName() const
    3007             :     {
    3008       16375 :         return m_osName;
    3009             :     }
    3010             : 
    3011             :     /** Return the name of an array or attribute.
    3012             :      *
    3013             :      * This is the same as the C function GDALMDArrayGetFullName() or
    3014             :      * GDALAttributeGetFullName().
    3015             :      */
    3016       10841 :     const std::string &GetFullName() const
    3017             :     {
    3018       10841 :         return m_osFullName;
    3019             :     }
    3020             : 
    3021             :     GUInt64 GetTotalElementsCount() const;
    3022             : 
    3023             :     virtual size_t GetDimensionCount() const;
    3024             : 
    3025             :     virtual const std::vector<std::shared_ptr<GDALDimension>> &
    3026             :     GetDimensions() const = 0;
    3027             : 
    3028             :     virtual const GDALExtendedDataType &GetDataType() const = 0;
    3029             : 
    3030             :     virtual std::vector<GUInt64> GetBlockSize() const;
    3031             : 
    3032             :     virtual std::vector<size_t>
    3033             :     GetProcessingChunkSize(size_t nMaxChunkMemory) const;
    3034             : 
    3035             :     /* clang-format off */
    3036             :     /** Type of pfnFunc argument of ProcessPerChunk().
    3037             :      * @param array Array on which ProcessPerChunk was called.
    3038             :      * @param chunkArrayStartIdx Values representing the starting index to use
    3039             :      *                           in each dimension (in [0, aoDims[i].GetSize()-1] range)
    3040             :      *                           for the current chunk.
    3041             :      *                           Will be nullptr for a zero-dimensional array.
    3042             :      * @param chunkCount         Values representing the number of values to use in
    3043             :      *                           each dimension for the current chunk.
    3044             :      *                           Will be nullptr for a zero-dimensional array.
    3045             :      * @param iCurChunk          Number of current chunk being processed.
    3046             :      *                           In [1, nChunkCount] range.
    3047             :      * @param nChunkCount        Total number of chunks to process.
    3048             :      * @param pUserData          User data.
    3049             :      * @return return true in case of success.
    3050             :      */
    3051             :     typedef bool (*FuncProcessPerChunkType)(
    3052             :                         GDALAbstractMDArray *array,
    3053             :                         const GUInt64 *chunkArrayStartIdx,
    3054             :                         const size_t *chunkCount,
    3055             :                         GUInt64 iCurChunk,
    3056             :                         GUInt64 nChunkCount,
    3057             :                         void *pUserData);
    3058             :     /* clang-format on */
    3059             : 
    3060             :     virtual bool ProcessPerChunk(const GUInt64 *arrayStartIdx,
    3061             :                                  const GUInt64 *count, const size_t *chunkSize,
    3062             :                                  FuncProcessPerChunkType pfnFunc,
    3063             :                                  void *pUserData);
    3064             : 
    3065             :     virtual bool
    3066             :     Read(const GUInt64 *arrayStartIdx,    // array of size GetDimensionCount()
    3067             :          const size_t *count,             // array of size GetDimensionCount()
    3068             :          const GInt64 *arrayStep,         // step in elements
    3069             :          const GPtrDiff_t *bufferStride,  // stride in elements
    3070             :          const GDALExtendedDataType &bufferDataType, void *pDstBuffer,
    3071             :          const void *pDstBufferAllocStart = nullptr,
    3072             :          size_t nDstBufferAllocSize = 0) const;
    3073             : 
    3074             :     bool
    3075             :     Write(const GUInt64 *arrayStartIdx,    // array of size GetDimensionCount()
    3076             :           const size_t *count,             // array of size GetDimensionCount()
    3077             :           const GInt64 *arrayStep,         // step in elements
    3078             :           const GPtrDiff_t *bufferStride,  // stride in elements
    3079             :           const GDALExtendedDataType &bufferDataType, const void *pSrcBuffer,
    3080             :           const void *pSrcBufferAllocStart = nullptr,
    3081             :           size_t nSrcBufferAllocSize = 0);
    3082             : 
    3083             :     virtual bool Rename(const std::string &osNewName);
    3084             : 
    3085             :     //! @cond Doxygen_Suppress
    3086             :     virtual void Deleted();
    3087             : 
    3088             :     virtual void ParentDeleted();
    3089             : 
    3090             :     virtual void ParentRenamed(const std::string &osNewParentFullName);
    3091             :     //! @endcond
    3092             : };
    3093             : 
    3094             : /* ******************************************************************** */
    3095             : /*                              GDALRawResult                           */
    3096             : /* ******************************************************************** */
    3097             : 
    3098             : /**
    3099             :  * Store the raw result of an attribute value, which might contain dynamically
    3100             :  * allocated structures (like pointer to strings).
    3101             :  *
    3102             :  * @since GDAL 3.1
    3103             :  */
    3104             : class CPL_DLL GDALRawResult
    3105             : {
    3106             :   private:
    3107             :     GDALExtendedDataType m_dt;
    3108             :     size_t m_nEltCount;
    3109             :     size_t m_nSize;
    3110             :     GByte *m_raw;
    3111             : 
    3112             :     void FreeMe();
    3113             : 
    3114             :     GDALRawResult(const GDALRawResult &) = delete;
    3115             :     GDALRawResult &operator=(const GDALRawResult &) = delete;
    3116             : 
    3117             :   protected:
    3118             :     friend class GDALAttribute;
    3119             :     //! @cond Doxygen_Suppress
    3120             :     GDALRawResult(GByte *raw, const GDALExtendedDataType &dt, size_t nEltCount);
    3121             :     //! @endcond
    3122             : 
    3123             :   public:
    3124             :     ~GDALRawResult();
    3125             :     GDALRawResult(GDALRawResult &&);
    3126             :     GDALRawResult &operator=(GDALRawResult &&);
    3127             : 
    3128             :     /** Return byte at specified index. */
    3129             :     const GByte &operator[](size_t idx) const
    3130             :     {
    3131             :         return m_raw[idx];
    3132             :     }
    3133             : 
    3134             :     /** Return pointer to the start of data. */
    3135         333 :     const GByte *data() const
    3136             :     {
    3137         333 :         return m_raw;
    3138             :     }
    3139             : 
    3140             :     /** Return the size in bytes of the raw result. */
    3141         121 :     size_t size() const
    3142             :     {
    3143         121 :         return m_nSize;
    3144             :     }
    3145             : 
    3146             :     //! @cond Doxygen_Suppress
    3147             :     GByte *StealData();
    3148             :     //! @endcond
    3149             : };
    3150             : 
    3151             : /* ******************************************************************** */
    3152             : /*                              GDALAttribute                           */
    3153             : /* ******************************************************************** */
    3154             : 
    3155             : /* clang-format off */
    3156             : /**
    3157             :  * Class modeling an attribute that has a name, a value and a type, and is
    3158             :  * typically used to describe a metadata item. The value can be (for the
    3159             :  * HDF5 format) in the general case a multidimensional array of "any" type
    3160             :  * (in most cases, this will be a single value of string or numeric type)
    3161             :  *
    3162             :  * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_attribute">HDF5
    3163             :  * attribute concept</a>
    3164             :  *
    3165             :  * @since GDAL 3.1
    3166             :  */
    3167             : /* clang-format on */
    3168             : 
    3169             : class CPL_DLL GDALAttribute : virtual public GDALAbstractMDArray
    3170             : {
    3171             :     mutable std::string m_osCachedVal{};
    3172             : 
    3173             :   protected:
    3174             :     //! @cond Doxygen_Suppress
    3175             :     GDALAttribute(const std::string &osParentName, const std::string &osName);
    3176             :     //! @endcond
    3177             : 
    3178             :   public:
    3179             :     std::vector<GUInt64> GetDimensionsSize() const;
    3180             : 
    3181             :     GDALRawResult ReadAsRaw() const;
    3182             :     const char *ReadAsString() const;
    3183             :     int ReadAsInt() const;
    3184             :     double ReadAsDouble() const;
    3185             :     CPLStringList ReadAsStringArray() const;
    3186             :     std::vector<int> ReadAsIntArray() const;
    3187             :     std::vector<double> ReadAsDoubleArray() const;
    3188             : 
    3189             :     using GDALAbstractMDArray::Write;
    3190             :     bool Write(const void *pabyValue, size_t nLen);
    3191             :     bool Write(const char *);
    3192             :     bool WriteInt(int);
    3193             :     bool Write(double);
    3194             :     bool Write(CSLConstList);
    3195             :     bool Write(const double *, size_t);
    3196             : 
    3197             :     //! @cond Doxygen_Suppress
    3198             :     static constexpr GUInt64 COPY_COST = 100;
    3199             :     //! @endcond
    3200             : };
    3201             : 
    3202             : /************************************************************************/
    3203             : /*                            GDALAttributeString                       */
    3204             : /************************************************************************/
    3205             : 
    3206             : //! @cond Doxygen_Suppress
    3207             : class CPL_DLL GDALAttributeString final : public GDALAttribute
    3208             : {
    3209             :     std::vector<std::shared_ptr<GDALDimension>> m_dims{};
    3210             :     GDALExtendedDataType m_dt = GDALExtendedDataType::CreateString();
    3211             :     std::string m_osValue;
    3212             : 
    3213             :   protected:
    3214             :     bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
    3215             :                const GPtrDiff_t *, const GDALExtendedDataType &bufferDataType,
    3216             :                void *pDstBuffer) const override;
    3217             : 
    3218             :   public:
    3219             :     GDALAttributeString(const std::string &osParentName,
    3220             :                         const std::string &osName, const std::string &osValue,
    3221             :                         GDALExtendedDataTypeSubType eSubType = GEDTST_NONE);
    3222             : 
    3223             :     const std::vector<std::shared_ptr<GDALDimension>> &
    3224             :     GetDimensions() const override;
    3225             : 
    3226             :     const GDALExtendedDataType &GetDataType() const override;
    3227             : };
    3228             : 
    3229             : //! @endcond
    3230             : 
    3231             : /************************************************************************/
    3232             : /*                           GDALAttributeNumeric                       */
    3233             : /************************************************************************/
    3234             : 
    3235             : //! @cond Doxygen_Suppress
    3236             : class CPL_DLL GDALAttributeNumeric final : public GDALAttribute
    3237             : {
    3238             :     std::vector<std::shared_ptr<GDALDimension>> m_dims{};
    3239             :     GDALExtendedDataType m_dt;
    3240             :     int m_nValue = 0;
    3241             :     double m_dfValue = 0;
    3242             :     std::vector<GUInt32> m_anValuesUInt32{};
    3243             : 
    3244             :   protected:
    3245             :     bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
    3246             :                const GPtrDiff_t *, const GDALExtendedDataType &bufferDataType,
    3247             :                void *pDstBuffer) const override;
    3248             : 
    3249             :   public:
    3250             :     GDALAttributeNumeric(const std::string &osParentName,
    3251             :                          const std::string &osName, double dfValue);
    3252             :     GDALAttributeNumeric(const std::string &osParentName,
    3253             :                          const std::string &osName, int nValue);
    3254             :     GDALAttributeNumeric(const std::string &osParentName,
    3255             :                          const std::string &osName,
    3256             :                          const std::vector<GUInt32> &anValues);
    3257             : 
    3258             :     const std::vector<std::shared_ptr<GDALDimension>> &
    3259             :     GetDimensions() const override;
    3260             : 
    3261             :     const GDALExtendedDataType &GetDataType() const override;
    3262             : };
    3263             : 
    3264             : //! @endcond
    3265             : 
    3266             : /* ******************************************************************** */
    3267             : /*                              GDALMDArray                             */
    3268             : /* ******************************************************************** */
    3269             : 
    3270             : /* clang-format off */
    3271             : /**
    3272             :  * Class modeling a multi-dimensional array. It has a name, values organized
    3273             :  * as an array and a list of GDALAttribute.
    3274             :  *
    3275             :  * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_dataset">HDF5
    3276             :  * dataset concept</a>
    3277             :  *
    3278             :  * @since GDAL 3.1
    3279             :  */
    3280             : /* clang-format on */
    3281             : 
    3282             : class CPL_DLL GDALMDArray : virtual public GDALAbstractMDArray,
    3283             :                             public GDALIHasAttribute
    3284             : {
    3285             :     friend class GDALMDArrayResampled;
    3286             :     std::shared_ptr<GDALMDArray>
    3287             :     GetView(const std::vector<GUInt64> &indices) const;
    3288             : 
    3289             :     inline std::shared_ptr<GDALMDArray>
    3290          19 :     atInternal(const std::vector<GUInt64> &indices) const
    3291             :     {
    3292          19 :         return GetView(indices);
    3293             :     }
    3294             : 
    3295             :     template <typename... GUInt64VarArg>
    3296             :     // cppcheck-suppress functionStatic
    3297             :     inline std::shared_ptr<GDALMDArray>
    3298           7 :     atInternal(std::vector<GUInt64> &indices, GUInt64 idx,
    3299             :                GUInt64VarArg... tail) const
    3300             :     {
    3301           7 :         indices.push_back(idx);
    3302           7 :         return atInternal(indices, tail...);
    3303             :     }
    3304             : 
    3305             :     // Used for example by GDALSubsetGroup to distinguish a derived group
    3306             :     //from its original, without altering its name
    3307             :     const std::string m_osContext{};
    3308             : 
    3309             :     mutable bool m_bHasTriedCachedArray = false;
    3310             :     mutable std::shared_ptr<GDALMDArray> m_poCachedArray{};
    3311             : 
    3312             :   protected:
    3313             :     //! @cond Doxygen_Suppress
    3314             :     GDALMDArray(const std::string &osParentName, const std::string &osName,
    3315             :                 const std::string &osContext = std::string());
    3316             : 
    3317             :     virtual bool IAdviseRead(const GUInt64 *arrayStartIdx, const size_t *count,
    3318             :                              CSLConstList papszOptions) const;
    3319             : 
    3320        1578 :     virtual bool IsCacheable() const
    3321             :     {
    3322        1578 :         return true;
    3323             :     }
    3324             : 
    3325             :     virtual bool SetStatistics(bool bApproxStats, double dfMin, double dfMax,
    3326             :                                double dfMean, double dfStdDev,
    3327             :                                GUInt64 nValidCount, CSLConstList papszOptions);
    3328             : 
    3329             :     static std::string MassageName(const std::string &inputName);
    3330             : 
    3331             :     std::shared_ptr<GDALGroup>
    3332             :     GetCacheRootGroup(bool bCanCreate, std::string &osCacheFilenameOut) const;
    3333             : 
    3334             :     // Returns if bufferStride values express a transposed view of the array
    3335             :     bool IsTransposedRequest(const size_t *count,
    3336             :                              const GPtrDiff_t *bufferStride) const;
    3337             : 
    3338             :     // Should only be called if IsTransposedRequest() returns true
    3339             :     bool ReadForTransposedRequest(const GUInt64 *arrayStartIdx,
    3340             :                                   const size_t *count, const GInt64 *arrayStep,
    3341             :                                   const GPtrDiff_t *bufferStride,
    3342             :                                   const GDALExtendedDataType &bufferDataType,
    3343             :                                   void *pDstBuffer) const;
    3344             : 
    3345             :     bool IsStepOneContiguousRowMajorOrderedSameDataType(
    3346             :         const size_t *count, const GInt64 *arrayStep,
    3347             :         const GPtrDiff_t *bufferStride,
    3348             :         const GDALExtendedDataType &bufferDataType) const;
    3349             : 
    3350             :     // Should only be called if IsStepOneContiguousRowMajorOrderedSameDataType()
    3351             :     // returns false
    3352             :     bool ReadUsingContiguousIRead(const GUInt64 *arrayStartIdx,
    3353             :                                   const size_t *count, const GInt64 *arrayStep,
    3354             :                                   const GPtrDiff_t *bufferStride,
    3355             :                                   const GDALExtendedDataType &bufferDataType,
    3356             :                                   void *pDstBuffer) const;
    3357             : 
    3358             :     static std::shared_ptr<GDALMDArray>
    3359             :     CreateGLTOrthorectified(const std::shared_ptr<GDALMDArray> &poParent,
    3360             :                             const std::shared_ptr<GDALMDArray> &poGLTX,
    3361             :                             const std::shared_ptr<GDALMDArray> &poGLTY,
    3362             :                             int nGLTIndexOffset,
    3363             :                             const std::vector<double> &adfGeoTransform);
    3364             : 
    3365             :     //! @endcond
    3366             : 
    3367             :   public:
    3368             :     GUInt64 GetTotalCopyCost() const;
    3369             : 
    3370             :     virtual bool CopyFrom(GDALDataset *poSrcDS, const GDALMDArray *poSrcArray,
    3371             :                           bool bStrict, GUInt64 &nCurCost,
    3372             :                           const GUInt64 nTotalCost,
    3373             :                           GDALProgressFunc pfnProgress, void *pProgressData);
    3374             : 
    3375             :     /** Return whether an array is writable. */
    3376             :     virtual bool IsWritable() const = 0;
    3377             : 
    3378             :     /** Return the filename that contains that array.
    3379             :      *
    3380             :      * This is used in particular for caching.
    3381             :      *
    3382             :      * Might be empty if the array is not linked to a file.
    3383             :      *
    3384             :      * @since GDAL 3.4
    3385             :      */
    3386             :     virtual const std::string &GetFilename() const = 0;
    3387             : 
    3388             :     virtual CSLConstList GetStructuralInfo() const;
    3389             : 
    3390             :     virtual const std::string &GetUnit() const;
    3391             : 
    3392             :     virtual bool SetUnit(const std::string &osUnit);
    3393             : 
    3394             :     virtual bool SetSpatialRef(const OGRSpatialReference *poSRS);
    3395             : 
    3396             :     virtual std::shared_ptr<OGRSpatialReference> GetSpatialRef() const;
    3397             : 
    3398             :     virtual const void *GetRawNoDataValue() const;
    3399             : 
    3400             :     double GetNoDataValueAsDouble(bool *pbHasNoData = nullptr) const;
    3401             : 
    3402             :     int64_t GetNoDataValueAsInt64(bool *pbHasNoData = nullptr) const;
    3403             : 
    3404             :     uint64_t GetNoDataValueAsUInt64(bool *pbHasNoData = nullptr) const;
    3405             : 
    3406             :     virtual bool SetRawNoDataValue(const void *pRawNoData);
    3407             : 
    3408             :     //! @cond Doxygen_Suppress
    3409           2 :     bool SetNoDataValue(int nNoData)
    3410             :     {
    3411           2 :         return SetNoDataValue(static_cast<int64_t>(nNoData));
    3412             :     }
    3413             : 
    3414             :     //! @endcond
    3415             : 
    3416             :     bool SetNoDataValue(double dfNoData);
    3417             : 
    3418             :     bool SetNoDataValue(int64_t nNoData);
    3419             : 
    3420             :     bool SetNoDataValue(uint64_t nNoData);
    3421             : 
    3422             :     virtual bool Resize(const std::vector<GUInt64> &anNewDimSizes,
    3423             :                         CSLConstList papszOptions);
    3424             : 
    3425             :     virtual double GetOffset(bool *pbHasOffset = nullptr,
    3426             :                              GDALDataType *peStorageType = nullptr) const;
    3427             : 
    3428             :     virtual double GetScale(bool *pbHasScale = nullptr,
    3429             :                             GDALDataType *peStorageType = nullptr) const;
    3430             : 
    3431             :     virtual bool SetOffset(double dfOffset,
    3432             :                            GDALDataType eStorageType = GDT_Unknown);
    3433             : 
    3434             :     virtual bool SetScale(double dfScale,
    3435             :                           GDALDataType eStorageType = GDT_Unknown);
    3436             : 
    3437             :     std::shared_ptr<GDALMDArray> GetView(const std::string &viewExpr) const;
    3438             : 
    3439             :     std::shared_ptr<GDALMDArray> operator[](const std::string &fieldName) const;
    3440             : 
    3441             :     /** Return a view of the array using integer indexing.
    3442             :      *
    3443             :      * Equivalent of GetView("[indices_0,indices_1,.....,indices_last]")
    3444             :      *
    3445             :      * Example:
    3446             :      * \code
    3447             :      * ar->at(0,3,2)
    3448             :      * \endcode
    3449             :      */
    3450             :     // sphinx 4.1.0 / breathe 4.30.0 don't like typename...
    3451             :     //! @cond Doxygen_Suppress
    3452             :     template <typename... GUInt64VarArg>
    3453             :     //! @endcond
    3454             :     // cppcheck-suppress functionStatic
    3455          19 :     std::shared_ptr<GDALMDArray> at(GUInt64 idx, GUInt64VarArg... tail) const
    3456             :     {
    3457          38 :         std::vector<GUInt64> indices;
    3458          19 :         indices.push_back(idx);
    3459          38 :         return atInternal(indices, tail...);
    3460             :     }
    3461             : 
    3462             :     virtual std::shared_ptr<GDALMDArray>
    3463             :     Transpose(const std::vector<int> &anMapNewAxisToOldAxis) const;
    3464             : 
    3465             :     std::shared_ptr<GDALMDArray> GetUnscaled(
    3466             :         double dfOverriddenScale = std::numeric_limits<double>::quiet_NaN(),
    3467             :         double dfOverriddenOffset = std::numeric_limits<double>::quiet_NaN(),
    3468             :         double dfOverriddenDstNodata =
    3469             :             std::numeric_limits<double>::quiet_NaN()) const;
    3470             : 
    3471             :     virtual std::shared_ptr<GDALMDArray>
    3472             :     GetMask(CSLConstList papszOptions) const;
    3473             : 
    3474             :     virtual std::shared_ptr<GDALMDArray>
    3475             :     GetResampled(const std::vector<std::shared_ptr<GDALDimension>> &apoNewDims,
    3476             :                  GDALRIOResampleAlg resampleAlg,
    3477             :                  const OGRSpatialReference *poTargetSRS,
    3478             :                  CSLConstList papszOptions) const;
    3479             : 
    3480             :     std::shared_ptr<GDALMDArray>
    3481             :     GetGridded(const std::string &osGridOptions,
    3482             :                const std::shared_ptr<GDALMDArray> &poXArray = nullptr,
    3483             :                const std::shared_ptr<GDALMDArray> &poYArray = nullptr,
    3484             :                CSLConstList papszOptions = nullptr) const;
    3485             : 
    3486             :     virtual GDALDataset *
    3487             :     AsClassicDataset(size_t iXDim, size_t iYDim,
    3488             :                      const std::shared_ptr<GDALGroup> &poRootGroup = nullptr,
    3489             :                      CSLConstList papszOptions = nullptr) const;
    3490             : 
    3491             :     virtual CPLErr GetStatistics(bool bApproxOK, bool bForce, double *pdfMin,
    3492             :                                  double *pdfMax, double *pdfMean,
    3493             :                                  double *padfStdDev, GUInt64 *pnValidCount,
    3494             :                                  GDALProgressFunc pfnProgress,
    3495             :                                  void *pProgressData);
    3496             : 
    3497             :     virtual bool ComputeStatistics(bool bApproxOK, double *pdfMin,
    3498             :                                    double *pdfMax, double *pdfMean,
    3499             :                                    double *pdfStdDev, GUInt64 *pnValidCount,
    3500             :                                    GDALProgressFunc, void *pProgressData,
    3501             :                                    CSLConstList papszOptions);
    3502             : 
    3503             :     virtual void ClearStatistics();
    3504             : 
    3505             :     virtual std::vector<std::shared_ptr<GDALMDArray>>
    3506             :     GetCoordinateVariables() const;
    3507             : 
    3508             :     bool AdviseRead(const GUInt64 *arrayStartIdx, const size_t *count,
    3509             :                     CSLConstList papszOptions = nullptr) const;
    3510             : 
    3511             :     bool IsRegularlySpaced(double &dfStart, double &dfIncrement) const;
    3512             : 
    3513             :     bool GuessGeoTransform(size_t nDimX, size_t nDimY, bool bPixelIsPoint,
    3514             :                            double adfGeoTransform[6]) const;
    3515             : 
    3516             :     bool Cache(CSLConstList papszOptions = nullptr) const;
    3517             : 
    3518             :     bool
    3519             :     Read(const GUInt64 *arrayStartIdx,    // array of size GetDimensionCount()
    3520             :          const size_t *count,             // array of size GetDimensionCount()
    3521             :          const GInt64 *arrayStep,         // step in elements
    3522             :          const GPtrDiff_t *bufferStride,  // stride in elements
    3523             :          const GDALExtendedDataType &bufferDataType, void *pDstBuffer,
    3524             :          const void *pDstBufferAllocStart = nullptr,
    3525             :          size_t nDstBufferAllocSize = 0) const override final;
    3526             : 
    3527             :     virtual std::shared_ptr<GDALGroup> GetRootGroup() const;
    3528             : 
    3529             :     //! @cond Doxygen_Suppress
    3530             :     static constexpr GUInt64 COPY_COST = 1000;
    3531             : 
    3532             :     bool CopyFromAllExceptValues(const GDALMDArray *poSrcArray, bool bStrict,
    3533             :                                  GUInt64 &nCurCost, const GUInt64 nTotalCost,
    3534             :                                  GDALProgressFunc pfnProgress,
    3535             :                                  void *pProgressData);
    3536             : 
    3537             :     struct Range
    3538             :     {
    3539             :         GUInt64 m_nStartIdx;
    3540             :         GInt64 m_nIncr;
    3541             : 
    3542        1281 :         explicit Range(GUInt64 nStartIdx = 0, GInt64 nIncr = 0)
    3543        1281 :             : m_nStartIdx(nStartIdx), m_nIncr(nIncr)
    3544             :         {
    3545        1281 :         }
    3546             :     };
    3547             : 
    3548             :     struct ViewSpec
    3549             :     {
    3550             :         std::string m_osFieldName{};
    3551             : 
    3552             :         // or
    3553             : 
    3554             :         std::vector<size_t>
    3555             :             m_mapDimIdxToParentDimIdx{};  // of size m_dims.size()
    3556             :         std::vector<Range>
    3557             :             m_parentRanges{};  // of size m_poParent->GetDimensionCount()
    3558             :     };
    3559             : 
    3560             :     virtual std::shared_ptr<GDALMDArray>
    3561             :     GetView(const std::string &viewExpr, bool bRenameDimensions,
    3562             :             std::vector<ViewSpec> &viewSpecs) const;
    3563             : 
    3564         970 :     const std::string &GetContext() const
    3565             :     {
    3566         970 :         return m_osContext;
    3567             :     }
    3568             : 
    3569             :     //! @endcond
    3570             : };
    3571             : 
    3572             : //! @cond Doxygen_Suppress
    3573             : bool GDALMDRasterIOFromBand(GDALRasterBand *poBand, GDALRWFlag eRWFlag,
    3574             :                             size_t iDimX, size_t iDimY,
    3575             :                             const GUInt64 *arrayStartIdx, const size_t *count,
    3576             :                             const GInt64 *arrayStep,
    3577             :                             const GPtrDiff_t *bufferStride,
    3578             :                             const GDALExtendedDataType &bufferDataType,
    3579             :                             void *pBuffer);
    3580             : 
    3581             : //! @endcond
    3582             : 
    3583             : /************************************************************************/
    3584             : /*                     GDALMDArrayRegularlySpaced                       */
    3585             : /************************************************************************/
    3586             : 
    3587             : //! @cond Doxygen_Suppress
    3588             : class CPL_DLL GDALMDArrayRegularlySpaced : public GDALMDArray
    3589             : {
    3590             :     double m_dfStart;
    3591             :     double m_dfIncrement;
    3592             :     double m_dfOffsetInIncrement;
    3593             :     GDALExtendedDataType m_dt = GDALExtendedDataType::Create(GDT_Float64);
    3594             :     std::vector<std::shared_ptr<GDALDimension>> m_dims;
    3595             :     std::vector<std::shared_ptr<GDALAttribute>> m_attributes{};
    3596             :     std::string m_osEmptyFilename{};
    3597             : 
    3598             :   protected:
    3599             :     bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
    3600             :                const GPtrDiff_t *, const GDALExtendedDataType &bufferDataType,
    3601             :                void *pDstBuffer) const override;
    3602             : 
    3603             :   public:
    3604             :     GDALMDArrayRegularlySpaced(const std::string &osParentName,
    3605             :                                const std::string &osName,
    3606             :                                const std::shared_ptr<GDALDimension> &poDim,
    3607             :                                double dfStart, double dfIncrement,
    3608             :                                double dfOffsetInIncrement);
    3609             : 
    3610             :     static std::shared_ptr<GDALMDArrayRegularlySpaced>
    3611             :     Create(const std::string &osParentName, const std::string &osName,
    3612             :            const std::shared_ptr<GDALDimension> &poDim, double dfStart,
    3613             :            double dfIncrement, double dfOffsetInIncrement);
    3614             : 
    3615           0 :     bool IsWritable() const override
    3616             :     {
    3617           0 :         return false;
    3618             :     }
    3619             : 
    3620         104 :     const std::string &GetFilename() const override
    3621             :     {
    3622         104 :         return m_osEmptyFilename;
    3623             :     }
    3624             : 
    3625             :     const std::vector<std::shared_ptr<GDALDimension>> &
    3626             :     GetDimensions() const override;
    3627             : 
    3628             :     const GDALExtendedDataType &GetDataType() const override;
    3629             : 
    3630             :     std::vector<std::shared_ptr<GDALAttribute>>
    3631             :         GetAttributes(CSLConstList) const override;
    3632             : 
    3633             :     void AddAttribute(const std::shared_ptr<GDALAttribute> &poAttr);
    3634             : };
    3635             : 
    3636             : //! @endcond
    3637             : 
    3638             : /* ******************************************************************** */
    3639             : /*                            GDALDimension                             */
    3640             : /* ******************************************************************** */
    3641             : 
    3642             : /**
    3643             :  * Class modeling a a dimension / axis used to index multidimensional arrays.
    3644             :  * It has a name, a size (that is the number of values that can be indexed along
    3645             :  * the dimension), a type (see GDALDimension::GetType()), a direction
    3646             :  * (see GDALDimension::GetDirection()), a unit and can optionally point to a
    3647             :  * GDALMDArray variable, typically one-dimensional, describing the values taken
    3648             :  * by the dimension. For a georeferenced GDALMDArray and its X dimension, this
    3649             :  * will be typically the values of the easting/longitude for each grid point.
    3650             :  *
    3651             :  * @since GDAL 3.1
    3652             :  */
    3653        7892 : class CPL_DLL GDALDimension
    3654             : {
    3655             :   public:
    3656             :     //! @cond Doxygen_Suppress
    3657             :     GDALDimension(const std::string &osParentName, const std::string &osName,
    3658             :                   const std::string &osType, const std::string &osDirection,
    3659             :                   GUInt64 nSize);
    3660             :     //! @endcond
    3661             : 
    3662             :     virtual ~GDALDimension();
    3663             : 
    3664             :     /** Return the name.
    3665             :      *
    3666             :      * This is the same as the C function GDALDimensionGetName()
    3667             :      */
    3668        7516 :     const std::string &GetName() const
    3669             :     {
    3670        7516 :         return m_osName;
    3671             :     }
    3672             : 
    3673             :     /** Return the full name.
    3674             :      *
    3675             :      * This is the same as the C function GDALDimensionGetFullName()
    3676             :      */
    3677        1226 :     const std::string &GetFullName() const
    3678             :     {
    3679        1226 :         return m_osFullName;
    3680             :     }
    3681             : 
    3682             :     /** Return the axis type.
    3683             :      *
    3684             :      * Predefined values are:
    3685             :      * HORIZONTAL_X, HORIZONTAL_Y, VERTICAL, TEMPORAL, PARAMETRIC
    3686             :      * Other values might be returned. Empty value means unknown.
    3687             :      *
    3688             :      * This is the same as the C function GDALDimensionGetType()
    3689             :      */
    3690        1629 :     const std::string &GetType() const
    3691             :     {
    3692        1629 :         return m_osType;
    3693             :     }
    3694             : 
    3695             :     /** Return the axis direction.
    3696             :      *
    3697             :      * Predefined values are:
    3698             :      * EAST, WEST, SOUTH, NORTH, UP, DOWN, FUTURE, PAST
    3699             :      * Other values might be returned. Empty value means unknown.
    3700             :      *
    3701             :      * This is the same as the C function GDALDimensionGetDirection()
    3702             :      */
    3703         833 :     const std::string &GetDirection() const
    3704             :     {
    3705         833 :         return m_osDirection;
    3706             :     }
    3707             : 
    3708             :     /** Return the size, that is the number of values along the dimension.
    3709             :      *
    3710             :      * This is the same as the C function GDALDimensionGetSize()
    3711             :      */
    3712       78581 :     GUInt64 GetSize() const
    3713             :     {
    3714       78581 :         return m_nSize;
    3715             :     }
    3716             : 
    3717             :     virtual std::shared_ptr<GDALMDArray> GetIndexingVariable() const;
    3718             : 
    3719             :     virtual bool
    3720             :     SetIndexingVariable(std::shared_ptr<GDALMDArray> poIndexingVariable);
    3721             : 
    3722             :     virtual bool Rename(const std::string &osNewName);
    3723             : 
    3724             :     //! @cond Doxygen_Suppress
    3725             :     virtual void ParentRenamed(const std::string &osNewParentFullName);
    3726             : 
    3727             :     virtual void ParentDeleted();
    3728             :     //! @endcond
    3729             : 
    3730             :   protected:
    3731             :     //! @cond Doxygen_Suppress
    3732             :     std::string m_osName;
    3733             :     std::string m_osFullName;
    3734             :     std::string m_osType;
    3735             :     std::string m_osDirection;
    3736             :     GUInt64 m_nSize;
    3737             : 
    3738             :     void BaseRename(const std::string &osNewName);
    3739             : 
    3740             :     //! @endcond
    3741             : };
    3742             : 
    3743             : /************************************************************************/
    3744             : /*                   GDALDimensionWeakIndexingVar()                     */
    3745             : /************************************************************************/
    3746             : 
    3747             : //! @cond Doxygen_Suppress
    3748             : class CPL_DLL GDALDimensionWeakIndexingVar : public GDALDimension
    3749             : {
    3750             :     std::weak_ptr<GDALMDArray> m_poIndexingVariable{};
    3751             : 
    3752             :   public:
    3753             :     GDALDimensionWeakIndexingVar(const std::string &osParentName,
    3754             :                                  const std::string &osName,
    3755             :                                  const std::string &osType,
    3756             :                                  const std::string &osDirection, GUInt64 nSize);
    3757             : 
    3758             :     std::shared_ptr<GDALMDArray> GetIndexingVariable() const override;
    3759             : 
    3760             :     bool SetIndexingVariable(
    3761             :         std::shared_ptr<GDALMDArray> poIndexingVariable) override;
    3762             : 
    3763             :     void SetSize(GUInt64 nNewSize);
    3764             : };
    3765             : //! @endcond
    3766             : 
    3767             : /************************************************************************/
    3768             : /*                       GDALAntiRecursionGuard                         */
    3769             : /************************************************************************/
    3770             : 
    3771             : //! @cond Doxygen_Suppress
    3772             : struct GDALAntiRecursionStruct;
    3773             : 
    3774             : class GDALAntiRecursionGuard
    3775             : {
    3776             :     GDALAntiRecursionStruct *m_psAntiRecursionStruct;
    3777             :     std::string m_osIdentifier;
    3778             :     int m_nDepth;
    3779             : 
    3780             :     GDALAntiRecursionGuard(const GDALAntiRecursionGuard &) = delete;
    3781             :     GDALAntiRecursionGuard &operator=(const GDALAntiRecursionGuard &) = delete;
    3782             : 
    3783             :   public:
    3784             :     explicit GDALAntiRecursionGuard(const std::string &osIdentifier);
    3785             :     GDALAntiRecursionGuard(const GDALAntiRecursionGuard &other,
    3786             :                            const std::string &osIdentifier);
    3787             :     ~GDALAntiRecursionGuard();
    3788             : 
    3789      105206 :     int GetCallDepth() const
    3790             :     {
    3791      105206 :         return m_nDepth;
    3792             :     }
    3793             : };
    3794             : 
    3795             : //! @endcond
    3796             : 
    3797             : /************************************************************************/
    3798             : /*                           Relationships                              */
    3799             : /************************************************************************/
    3800             : 
    3801             : /**
    3802             :  * Definition of a table relationship.
    3803             :  *
    3804             :  * GDALRelationship describes the relationship between two tables, including
    3805             :  * properties such as the cardinality of the relationship and the participating
    3806             :  * tables.
    3807             :  *
    3808             :  * Not all relationship properties are supported by all data formats.
    3809             :  *
    3810             :  * @since GDAL 3.6
    3811             :  */
    3812             : class CPL_DLL GDALRelationship
    3813             : {
    3814             :   protected:
    3815             :     /*! @cond Doxygen_Suppress */
    3816             :     std::string m_osName{};
    3817             :     std::string m_osLeftTableName{};
    3818             :     std::string m_osRightTableName{};
    3819             :     GDALRelationshipCardinality m_eCardinality =
    3820             :         GDALRelationshipCardinality::GRC_ONE_TO_MANY;
    3821             :     std::string m_osMappingTableName{};
    3822             :     std::vector<std::string> m_osListLeftTableFields{};
    3823             :     std::vector<std::string> m_osListRightTableFields{};
    3824             :     std::vector<std::string> m_osListLeftMappingTableFields{};
    3825             :     std::vector<std::string> m_osListRightMappingTableFields{};
    3826             :     GDALRelationshipType m_eType = GDALRelationshipType::GRT_ASSOCIATION;
    3827             :     std::string m_osForwardPathLabel{};
    3828             :     std::string m_osBackwardPathLabel{};
    3829             :     std::string m_osRelatedTableType{};
    3830             : 
    3831             :     /*! @endcond */
    3832             : 
    3833             :   public:
    3834             :     /**
    3835             :      * Constructor for a relationship between two tables.
    3836             :      * @param osName relationship name
    3837             :      * @param osLeftTableName left table name
    3838             :      * @param osRightTableName right table name
    3839             :      * @param eCardinality cardinality of relationship
    3840             :      */
    3841         317 :     GDALRelationship(const std::string &osName,
    3842             :                      const std::string &osLeftTableName,
    3843             :                      const std::string &osRightTableName,
    3844             :                      GDALRelationshipCardinality eCardinality =
    3845             :                          GDALRelationshipCardinality::GRC_ONE_TO_MANY)
    3846         317 :         : m_osName(osName), m_osLeftTableName(osLeftTableName),
    3847         317 :           m_osRightTableName(osRightTableName), m_eCardinality(eCardinality)
    3848             :     {
    3849         317 :     }
    3850             : 
    3851             :     /** Get the name of the relationship */
    3852         305 :     const std::string &GetName() const
    3853             :     {
    3854         305 :         return m_osName;
    3855             :     }
    3856             : 
    3857             :     /** Get the cardinality of the relationship */
    3858         163 :     GDALRelationshipCardinality GetCardinality() const
    3859             :     {
    3860         163 :         return m_eCardinality;
    3861             :     }
    3862             : 
    3863             :     /** Get the name of the left (or base/origin) table in the relationship.
    3864             :      *
    3865             :      * @see GetRightTableName()
    3866             :      */
    3867         155 :     const std::string &GetLeftTableName() const
    3868             :     {
    3869         155 :         return m_osLeftTableName;
    3870             :     }
    3871             : 
    3872             :     /** Get the name of the right (or related/destination) table in the
    3873             :      * relationship */
    3874         151 :     const std::string &GetRightTableName() const
    3875             :     {
    3876         151 :         return m_osRightTableName;
    3877             :     }
    3878             : 
    3879             :     /** Get the name of the mapping table for many-to-many relationships.
    3880             :      *
    3881             :      * @see SetMappingTableName()
    3882             :      */
    3883         127 :     const std::string &GetMappingTableName() const
    3884             :     {
    3885         127 :         return m_osMappingTableName;
    3886             :     }
    3887             : 
    3888             :     /** Sets the name of the mapping table for many-to-many relationships.
    3889             :      *
    3890             :      * @see GetMappingTableName()
    3891             :      */
    3892         103 :     void SetMappingTableName(const std::string &osName)
    3893             :     {
    3894         103 :         m_osMappingTableName = osName;
    3895         103 :     }
    3896             : 
    3897             :     /** Get the names of the participating fields from the left table in the
    3898             :      * relationship.
    3899             :      *
    3900             :      * @see GetRightTableFields()
    3901             :      * @see SetLeftTableFields()
    3902             :      */
    3903         133 :     const std::vector<std::string> &GetLeftTableFields() const
    3904             :     {
    3905         133 :         return m_osListLeftTableFields;
    3906             :     }
    3907             : 
    3908             :     /** Get the names of the participating fields from the right table in the
    3909             :      * relationship.
    3910             :      *
    3911             :      * @see GetLeftTableFields()
    3912             :      * @see SetRightTableFields()
    3913             :      */
    3914         127 :     const std::vector<std::string> &GetRightTableFields() const
    3915             :     {
    3916         127 :         return m_osListRightTableFields;
    3917             :     }
    3918             : 
    3919             :     /** Sets the names of the participating fields from the left table in the
    3920             :      * relationship.
    3921             :      *
    3922             :      * @see GetLeftTableFields()
    3923             :      * @see SetRightTableFields()
    3924             :      */
    3925         330 :     void SetLeftTableFields(const std::vector<std::string> &osListFields)
    3926             :     {
    3927         330 :         m_osListLeftTableFields = osListFields;
    3928         330 :     }
    3929             : 
    3930             :     /** Sets the names of the participating fields from the right table in the
    3931             :      * relationship.
    3932             :      *
    3933             :      * @see GetRightTableFields()
    3934             :      * @see SetLeftTableFields()
    3935             :      */
    3936         331 :     void SetRightTableFields(const std::vector<std::string> &osListFields)
    3937             :     {
    3938         331 :         m_osListRightTableFields = osListFields;
    3939         331 :     }
    3940             : 
    3941             :     /** Get the names of the mapping table fields which correspond to the
    3942             :      * participating fields from the left table in the relationship.
    3943             :      *
    3944             :      * @see GetRightMappingTableFields()
    3945             :      * @see SetLeftMappingTableFields()
    3946             :      */
    3947          53 :     const std::vector<std::string> &GetLeftMappingTableFields() const
    3948             :     {
    3949          53 :         return m_osListLeftMappingTableFields;
    3950             :     }
    3951             : 
    3952             :     /** Get the names of the mapping table fields which correspond to the
    3953             :      * participating fields from the right table in the relationship.
    3954             :      *
    3955             :      * @see GetLeftMappingTableFields()
    3956             :      * @see SetRightMappingTableFields()
    3957             :      */
    3958          53 :     const std::vector<std::string> &GetRightMappingTableFields() const
    3959             :     {
    3960          53 :         return m_osListRightMappingTableFields;
    3961             :     }
    3962             : 
    3963             :     /** Sets the names of the mapping table fields which correspond to the
    3964             :      * participating fields from the left table in the relationship.
    3965             :      *
    3966             :      * @see GetLeftMappingTableFields()
    3967             :      * @see SetRightMappingTableFields()
    3968             :      */
    3969         281 :     void SetLeftMappingTableFields(const std::vector<std::string> &osListFields)
    3970             :     {
    3971         281 :         m_osListLeftMappingTableFields = osListFields;
    3972         281 :     }
    3973             : 
    3974             :     /** Sets the names of the mapping table fields which correspond to the
    3975             :      * participating fields from the right table in the relationship.
    3976             :      *
    3977             :      * @see GetRightMappingTableFields()
    3978             :      * @see SetLeftMappingTableFields()
    3979             :      */
    3980             :     void
    3981         281 :     SetRightMappingTableFields(const std::vector<std::string> &osListFields)
    3982             :     {
    3983         281 :         m_osListRightMappingTableFields = osListFields;
    3984         281 :     }
    3985             : 
    3986             :     /** Get the type of the relationship.
    3987             :      *
    3988             :      * @see SetType()
    3989             :      */
    3990         101 :     GDALRelationshipType GetType() const
    3991             :     {
    3992         101 :         return m_eType;
    3993             :     }
    3994             : 
    3995             :     /** Sets the type of the relationship.
    3996             :      *
    3997             :      * @see GetType()
    3998             :      */
    3999         237 :     void SetType(GDALRelationshipType eType)
    4000             :     {
    4001         237 :         m_eType = eType;
    4002         237 :     }
    4003             : 
    4004             :     /** Get the label of the forward path for the relationship.
    4005             :      *
    4006             :      * The forward and backward path labels are free-form, user-friendly strings
    4007             :      * which can be used to generate descriptions of the relationship between
    4008             :      * features from the right and left tables.
    4009             :      *
    4010             :      * E.g. when the left table contains buildings and the right table contains
    4011             :      * furniture, the forward path label could be "contains" and the backward
    4012             :      * path label could be "is located within". A client could then generate a
    4013             :      * user friendly description string such as "fire hose 1234 is located
    4014             :      * within building 15a".
    4015             :      *
    4016             :      * @see SetForwardPathLabel()
    4017             :      * @see GetBackwardPathLabel()
    4018             :      */
    4019          43 :     const std::string &GetForwardPathLabel() const
    4020             :     {
    4021          43 :         return m_osForwardPathLabel;
    4022             :     }
    4023             : 
    4024             :     /** Sets the label of the forward path for the relationship.
    4025             :      *
    4026             :      * The forward and backward path labels are free-form, user-friendly strings
    4027             :      * which can be used to generate descriptions of the relationship between
    4028             :      * features from the right and left tables.
    4029             :      *
    4030             :      * E.g. when the left table contains buildings and the right table contains
    4031             :      * furniture, the forward path label could be "contains" and the backward
    4032             :      * path label could be "is located within". A client could then generate a
    4033             :      * user friendly description string such as "fire hose 1234 is located
    4034             :      * within building 15a".
    4035             :      *
    4036             :      * @see GetForwardPathLabel()
    4037             :      * @see SetBackwardPathLabel()
    4038             :      */
    4039         234 :     void SetForwardPathLabel(const std::string &osLabel)
    4040             :     {
    4041         234 :         m_osForwardPathLabel = osLabel;
    4042         234 :     }
    4043             : 
    4044             :     /** Get the label of the backward path for the relationship.
    4045             :      *
    4046             :      * The forward and backward path labels are free-form, user-friendly strings
    4047             :      * which can be used to generate descriptions of the relationship between
    4048             :      * features from the right and left tables.
    4049             :      *
    4050             :      * E.g. when the left table contains buildings and the right table contains
    4051             :      * furniture, the forward path label could be "contains" and the backward
    4052             :      * path label could be "is located within". A client could then generate a
    4053             :      * user friendly description string such as "fire hose 1234 is located
    4054             :      * within building 15a".
    4055             :      *
    4056             :      * @see SetBackwardPathLabel()
    4057             :      * @see GetForwardPathLabel()
    4058             :      */
    4059          43 :     const std::string &GetBackwardPathLabel() const
    4060             :     {
    4061          43 :         return m_osBackwardPathLabel;
    4062             :     }
    4063             : 
    4064             :     /** Sets the label of the backward path for the relationship.
    4065             :      *
    4066             :      * The forward and backward path labels are free-form, user-friendly strings
    4067             :      * which can be used to generate descriptions of the relationship between
    4068             :      * features from the right and left tables.
    4069             :      *
    4070             :      * E.g. when the left table contains buildings and the right table contains
    4071             :      * furniture, the forward path label could be "contains" and the backward
    4072             :      * path label could be "is located within". A client could then generate a
    4073             :      * user friendly description string such as "fire hose 1234 is located
    4074             :      * within building 15a".
    4075             :      *
    4076             :      * @see GetBackwardPathLabel()
    4077             :      * @see SetForwardPathLabel()
    4078             :      */
    4079         234 :     void SetBackwardPathLabel(const std::string &osLabel)
    4080             :     {
    4081         234 :         m_osBackwardPathLabel = osLabel;
    4082         234 :     }
    4083             : 
    4084             :     /** Get the type string of the related table.
    4085             :      *
    4086             :      * This a free-form string representing the type of related features, where
    4087             :      * the exact interpretation is format dependent. For instance, table types
    4088             :      * from GeoPackage relationships will directly reflect the categories from
    4089             :      * the GeoPackage related tables extension (i.e. "media", "simple
    4090             :      * attributes", "features", "attributes" and "tiles").
    4091             :      *
    4092             :      * @see SetRelatedTableType()
    4093             :      */
    4094         124 :     const std::string &GetRelatedTableType() const
    4095             :     {
    4096         124 :         return m_osRelatedTableType;
    4097             :     }
    4098             : 
    4099             :     /** Sets the type string of the related table.
    4100             :      *
    4101             :      * This a free-form string representing the type of related features, where
    4102             :      * the exact interpretation is format dependent. For instance, table types
    4103             :      * from GeoPackage relationships will directly reflect the categories from
    4104             :      * the GeoPackage related tables extension (i.e. "media", "simple
    4105             :      * attributes", "features", "attributes" and "tiles").
    4106             :      *
    4107             :      * @see GetRelatedTableType()
    4108             :      */
    4109         308 :     void SetRelatedTableType(const std::string &osType)
    4110             :     {
    4111         308 :         m_osRelatedTableType = osType;
    4112         308 :     }
    4113             : 
    4114             :     /** Convert a GDALRelationship* to a GDALRelationshipH.
    4115             :      */
    4116          79 :     static inline GDALRelationshipH ToHandle(GDALRelationship *poRelationship)
    4117             :     {
    4118          79 :         return static_cast<GDALRelationshipH>(poRelationship);
    4119             :     }
    4120             : 
    4121             :     /** Convert a GDALRelationshipH to a GDALRelationship*.
    4122             :      */
    4123         700 :     static inline GDALRelationship *FromHandle(GDALRelationshipH hRelationship)
    4124             :     {
    4125         700 :         return static_cast<GDALRelationship *>(hRelationship);
    4126             :     }
    4127             : };
    4128             : 
    4129             : /* ==================================================================== */
    4130             : /*      An assortment of overview related stuff.                        */
    4131             : /* ==================================================================== */
    4132             : 
    4133             : //! @cond Doxygen_Suppress
    4134             : /* Only exported for drivers as plugin. Signature may change */
    4135             : CPLErr CPL_DLL GDALRegenerateOverviewsMultiBand(
    4136             :     int nBands, GDALRasterBand *const *papoSrcBands, int nOverviews,
    4137             :     GDALRasterBand *const *const *papapoOverviewBands,
    4138             :     const char *pszResampling, GDALProgressFunc pfnProgress,
    4139             :     void *pProgressData, CSLConstList papszOptions);
    4140             : 
    4141             : typedef CPLErr (*GDALResampleFunction)(
    4142             :     double dfXRatioDstToSrc, double dfYRatioDstToSrc, double dfSrcXDelta,
    4143             :     double dfSrcYDelta, GDALDataType eWrkDataType, const void *pChunk,
    4144             :     const GByte *pabyChunkNodataMask, int nChunkXOff, int nChunkXSize,
    4145             :     int nChunkYOff, int nChunkYSize, int nDstXOff, int nDstXOff2, int nDstYOff,
    4146             :     int nDstYOff2, GDALRasterBand *poOverview, void **ppDstBuffer,
    4147             :     GDALDataType *peDstBufferDataType, const char *pszResampling,
    4148             :     bool bHasNoData, double dfNoDataValue, GDALColorTable *poColorTable,
    4149             :     GDALDataType eSrcDataType, bool bPropagateNoData);
    4150             : 
    4151             : GDALResampleFunction GDALGetResampleFunction(const char *pszResampling,
    4152             :                                              int *pnRadius);
    4153             : 
    4154             : std::string GDALGetNormalizedOvrResampling(const char *pszResampling);
    4155             : 
    4156             : GDALDataType GDALGetOvrWorkDataType(const char *pszResampling,
    4157             :                                     GDALDataType eSrcDataType);
    4158             : 
    4159             : CPL_C_START
    4160             : 
    4161             : CPLErr CPL_DLL
    4162             : HFAAuxBuildOverviews(const char *pszOvrFilename, GDALDataset *poParentDS,
    4163             :                      GDALDataset **ppoDS, int nBands, const int *panBandList,
    4164             :                      int nNewOverviews, const int *panNewOverviewList,
    4165             :                      const char *pszResampling, GDALProgressFunc pfnProgress,
    4166             :                      void *pProgressData, CSLConstList papszOptions);
    4167             : 
    4168             : CPLErr CPL_DLL GTIFFBuildOverviews(const char *pszFilename, int nBands,
    4169             :                                    GDALRasterBand *const *papoBandList,
    4170             :                                    int nOverviews, const int *panOverviewList,
    4171             :                                    const char *pszResampling,
    4172             :                                    GDALProgressFunc pfnProgress,
    4173             :                                    void *pProgressData,
    4174             :                                    CSLConstList papszOptions);
    4175             : 
    4176             : int CPL_DLL GDALBandGetBestOverviewLevel(GDALRasterBand *poBand, int &nXOff,
    4177             :                                          int &nYOff, int &nXSize, int &nYSize,
    4178             :                                          int nBufXSize, int nBufYSize)
    4179             :     CPL_WARN_DEPRECATED("Use GDALBandGetBestOverviewLevel2 instead");
    4180             : int CPL_DLL GDALBandGetBestOverviewLevel2(GDALRasterBand *poBand, int &nXOff,
    4181             :                                           int &nYOff, int &nXSize, int &nYSize,
    4182             :                                           int nBufXSize, int nBufYSize,
    4183             :                                           GDALRasterIOExtraArg *psExtraArg);
    4184             : 
    4185             : int CPL_DLL GDALOvLevelAdjust(int nOvLevel, int nXSize)
    4186             :     CPL_WARN_DEPRECATED("Use GDALOvLevelAdjust2 instead");
    4187             : int CPL_DLL GDALOvLevelAdjust2(int nOvLevel, int nXSize, int nYSize);
    4188             : int CPL_DLL GDALComputeOvFactor(int nOvrXSize, int nRasterXSize, int nOvrYSize,
    4189             :                                 int nRasterYSize);
    4190             : 
    4191             : GDALDataset CPL_DLL *GDALFindAssociatedAuxFile(const char *pszBasefile,
    4192             :                                                GDALAccess eAccess,
    4193             :                                                GDALDataset *poDependentDS);
    4194             : 
    4195             : /* ==================================================================== */
    4196             : /*  Infrastructure to check that dataset characteristics are valid      */
    4197             : /* ==================================================================== */
    4198             : 
    4199             : int CPL_DLL GDALCheckDatasetDimensions(int nXSize, int nYSize);
    4200             : int CPL_DLL GDALCheckBandCount(int nBands, int bIsZeroAllowed);
    4201             : 
    4202             : /* Internal use only */
    4203             : 
    4204             : /* CPL_DLL exported, but only for in-tree drivers that can be built as plugins
    4205             :  */
    4206             : int CPL_DLL GDALReadWorldFile2(const char *pszBaseFilename,
    4207             :                                const char *pszExtension,
    4208             :                                double *padfGeoTransform,
    4209             :                                char **papszSiblingFiles,
    4210             :                                char **ppszWorldFileNameOut);
    4211             : int CPL_DLL GDALReadTabFile2(const char *pszBaseFilename,
    4212             :                              double *padfGeoTransform, char **ppszWKT,
    4213             :                              int *pnGCPCount, GDAL_GCP **ppasGCPs,
    4214             :                              char **papszSiblingFiles,
    4215             :                              char **ppszTabFileNameOut);
    4216             : 
    4217             : void CPL_DLL GDALCopyRasterIOExtraArg(GDALRasterIOExtraArg *psDestArg,
    4218             :                                       GDALRasterIOExtraArg *psSrcArg);
    4219             : 
    4220             : CPL_C_END
    4221             : 
    4222             : void GDALNullifyOpenDatasetsList();
    4223             : CPLMutex **GDALGetphDMMutex();
    4224             : CPLMutex **GDALGetphDLMutex();
    4225             : void GDALNullifyProxyPoolSingleton();
    4226             : void GDALSetResponsiblePIDForCurrentThread(GIntBig responsiblePID);
    4227             : GIntBig GDALGetResponsiblePIDForCurrentThread();
    4228             : 
    4229             : CPLString GDALFindAssociatedFile(const char *pszBasename, const char *pszExt,
    4230             :                                  CSLConstList papszSiblingFiles, int nFlags);
    4231             : 
    4232             : CPLErr CPL_DLL EXIFExtractMetadata(char **&papszMetadata, void *fpL,
    4233             :                                    int nOffset, int bSwabflag, int nTIFFHEADER,
    4234             :                                    int &nExifOffset, int &nInterOffset,
    4235             :                                    int &nGPSOffset);
    4236             : 
    4237             : int GDALValidateOpenOptions(GDALDriverH hDriver,
    4238             :                             const char *const *papszOptionOptions);
    4239             : int GDALValidateOptions(const char *pszOptionList,
    4240             :                         const char *const *papszOptionsToValidate,
    4241             :                         const char *pszErrorMessageOptionType,
    4242             :                         const char *pszErrorMessageContainerName);
    4243             : 
    4244             : GDALRIOResampleAlg GDALRasterIOGetResampleAlg(const char *pszResampling);
    4245             : const char *GDALRasterIOGetResampleAlg(GDALRIOResampleAlg eResampleAlg);
    4246             : 
    4247             : void GDALRasterIOExtraArgSetResampleAlg(GDALRasterIOExtraArg *psExtraArg,
    4248             :                                         int nXSize, int nYSize, int nBufXSize,
    4249             :                                         int nBufYSize);
    4250             : 
    4251             : GDALDataset *GDALCreateOverviewDataset(GDALDataset *poDS, int nOvrLevel,
    4252             :                                        bool bThisLevelOnly);
    4253             : 
    4254             : // Should cover particular cases of #3573, #4183, #4506, #6578
    4255             : // Behavior is undefined if fVal1 or fVal2 are NaN (should be tested before
    4256             : // calling this function)
    4257    16263404 : template <class T> inline bool ARE_REAL_EQUAL(T fVal1, T fVal2, int ulp = 2)
    4258             : {
    4259    31492397 :     return fVal1 == fVal2 || /* Should cover infinity */
    4260    15228993 :            std::abs(fVal1 - fVal2) < std::numeric_limits<float>::epsilon() *
    4261    31492397 :                                          std::abs(fVal1 + fVal2) * ulp;
    4262             : }
    4263             : 
    4264             : double GDALAdjustNoDataCloseToFloatMax(double dfVal);
    4265             : 
    4266             : #define DIV_ROUND_UP(a, b) (((a) % (b)) == 0 ? ((a) / (b)) : (((a) / (b)) + 1))
    4267             : 
    4268             : // Number of data samples that will be used to compute approximate statistics
    4269             : // (minimum value, maximum value, etc.)
    4270             : #define GDALSTAT_APPROX_NUMSAMPLES 2500
    4271             : 
    4272             : void GDALSerializeGCPListToXML(CPLXMLNode *psParentNode,
    4273             :                                const std::vector<gdal::GCP> &asGCPs,
    4274             :                                const OGRSpatialReference *poGCP_SRS);
    4275             : void GDALDeserializeGCPListFromXML(const CPLXMLNode *psGCPList,
    4276             :                                    std::vector<gdal::GCP> &asGCPs,
    4277             :                                    OGRSpatialReference **ppoGCP_SRS);
    4278             : 
    4279             : void GDALSerializeOpenOptionsToXML(CPLXMLNode *psParentNode,
    4280             :                                    char **papszOpenOptions);
    4281             : char **GDALDeserializeOpenOptionsFromXML(const CPLXMLNode *psParentNode);
    4282             : 
    4283             : int GDALCanFileAcceptSidecarFile(const char *pszFilename);
    4284             : 
    4285             : bool GDALCanReliablyUseSiblingFileList(const char *pszFilename);
    4286             : 
    4287             : typedef enum
    4288             : {
    4289             :     GSF_UNSIGNED_INT,
    4290             :     GSF_SIGNED_INT,
    4291             :     GSF_FLOATING_POINT,
    4292             : } GDALBufferSampleFormat;
    4293             : 
    4294             : bool CPL_DLL GDALBufferHasOnlyNoData(const void *pBuffer, double dfNoDataValue,
    4295             :                                      size_t nWidth, size_t nHeight,
    4296             :                                      size_t nLineStride, size_t nComponents,
    4297             :                                      int nBitsPerSample,
    4298             :                                      GDALBufferSampleFormat nSampleFormat);
    4299             : 
    4300             : void CPL_DLL GDALCopyNoDataValue(GDALRasterBand *poDstBand,
    4301             :                                  GDALRasterBand *poSrcBand);
    4302             : 
    4303             : double CPL_DLL GDALGetNoDataValueCastToDouble(int64_t nVal);
    4304             : double CPL_DLL GDALGetNoDataValueCastToDouble(uint64_t nVal);
    4305             : 
    4306             : // Remove me in GDAL 4.0. See GetMetadataItem() implementation
    4307             : // Internal use in GDAL only !
    4308             : // Declaration copied in swig/include/gdal.i
    4309             : void CPL_DLL GDALEnablePixelTypeSignedByteWarning(GDALRasterBandH hBand,
    4310             :                                                   bool b);
    4311             : 
    4312             : std::string CPL_DLL GDALGetCompressionFormatForJPEG(VSILFILE *fp);
    4313             : std::string CPL_DLL GDALGetCompressionFormatForJPEG(const void *pBuffer,
    4314             :                                                     size_t nBufferSize);
    4315             : 
    4316             : GDALRasterAttributeTable CPL_DLL *GDALCreateRasterAttributeTableFromMDArrays(
    4317             :     GDALRATTableType eTableType,
    4318             :     const std::vector<std::shared_ptr<GDALMDArray>> &apoArrays,
    4319             :     const std::vector<GDALRATFieldUsage> &aeUsages);
    4320             : 
    4321             : //! @endcond
    4322             : 
    4323             : #endif /* ndef GDAL_PRIV_H_INCLUDED */

Generated by: LCOV version 1.14