LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/generic - ogrsfdriverregistrar.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 52 116 44.8 %
Date: 2025-10-22 13:51:22 Functions: 13 23 56.5 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  The OGRSFDriverRegistrar class implementation.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 1999,  Les Technologies SoftMap Inc.
       9             :  * Copyright (c) 2008-2012, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "ogrsf_frmts.h"
      15             : #include "ogr_api.h"
      16             : #include "ograpispy.h"
      17             : 
      18             : /************************************************************************/
      19             : /*                         OGRSFDriverRegistrar                         */
      20             : /************************************************************************/
      21             : 
      22             : /**
      23             :  * \brief Constructor
      24             :  *
      25             :  * Normally the driver registrar is constructed by the
      26             :  * OGRSFDriverRegistrar::GetRegistrar() accessor which ensures singleton
      27             :  * status.
      28             :  */
      29             : 
      30         307 : OGRSFDriverRegistrar::OGRSFDriverRegistrar()
      31             : {
      32         307 : }
      33             : 
      34             : /************************************************************************/
      35             : /*                       ~OGRSFDriverRegistrar()                        */
      36             : /************************************************************************/
      37             : 
      38         307 : OGRSFDriverRegistrar::~OGRSFDriverRegistrar()
      39             : {
      40         307 : }
      41             : 
      42             : //! @cond Doxygen_Suppress
      43             : /************************************************************************/
      44             : /*                           GetRegistrar()                             */
      45             : /************************************************************************/
      46             : 
      47        3113 : OGRSFDriverRegistrar *OGRSFDriverRegistrar::GetRegistrar()
      48             : {
      49        3113 :     static OGRSFDriverRegistrar oSingleton;
      50        3113 :     return &oSingleton;
      51             : }
      52             : 
      53             : //! @endcond
      54             : 
      55             : /************************************************************************/
      56             : /*                           OGRCleanupAll()                            */
      57             : /************************************************************************/
      58             : 
      59             : /**
      60             :  * \brief Cleanup all OGR related resources.
      61             :  *
      62             :  * \see GDALDestroy()
      63             :  * \deprecated Use GDALDestroy() instead
      64             :  */
      65         783 : void OGRCleanupAll()
      66             : 
      67             : {
      68         783 :     GDALDestroyDriverManager();
      69         783 : }
      70             : 
      71             : /************************************************************************/
      72             : /*                              OGROpen()                               */
      73             : /************************************************************************/
      74             : 
      75             : /**
      76             :   \brief Open a file / data source with one of the registered drivers.
      77             : 
      78             :   This function loops through all the drivers registered with the driver
      79             :   manager trying each until one succeeds with the given data source.
      80             : 
      81             :   If this function fails, CPLGetLastErrorMsg() can be used to check if there
      82             :   is an error message explaining why.
      83             : 
      84             :   For drivers supporting the VSI virtual file API, it is possible to open
      85             :   a file in a .zip archive (see VSIInstallZipFileHandler()), in a .tar/.tar.gz/.tgz archive
      86             :   (see VSIInstallTarFileHandler()) or on a HTTP / FTP server (see VSIInstallCurlFileHandler())
      87             : 
      88             :   NOTE: It is *NOT* safe to cast the returned handle to
      89             :   OGRDataSource*. If a C++ object is needed, the handle should be cast to GDALDataset*.
      90             :   Similarly, the returned OGRSFDriverH handle should be cast to GDALDriver*, and
      91             :   *NOT* OGRSFDriver*.
      92             : 
      93             :   @deprecated Use GDALOpenEx()
      94             : 
      95             :   @param pszName the name of the file, or data source to open.
      96             :   @param bUpdate FALSE for read-only access (the default) or TRUE for
      97             :          read-write access.
      98             :   @param pahDriverList if non-NULL, this argument will be updated with a
      99             :          pointer to the driver which was used to open the data source.
     100             : 
     101             :   @return NULL on error or if the pass name is not supported by this driver,
     102             :   otherwise a handle to a GDALDataset.  This GDALDataset should be
     103             :   closed by deleting the object when it is no longer needed.
     104             : 
     105             :   Example:
     106             : 
     107             :   \code{.cpp}
     108             :     OGRDataSourceH hDS;
     109             :     OGRSFDriverH *pahDriver;
     110             : 
     111             :     hDS = OGROpen( "polygon.shp", 0, pahDriver );
     112             :     if( hDS == NULL )
     113             :     {
     114             :         return;
     115             :     }
     116             : 
     117             :     ... use the data source ...
     118             : 
     119             :     OGRReleaseDataSource( hDS );
     120             :   \endcode
     121             : 
     122             : */
     123             : 
     124         178 : OGRDataSourceH OGROpen(const char *pszName, int bUpdate,
     125             :                        OGRSFDriverH *pahDriverList)
     126             : 
     127             : {
     128         178 :     VALIDATE_POINTER1(pszName, "OGROpen", nullptr);
     129             : 
     130             :     GDALDatasetH hDS =
     131         178 :         GDALOpenEx(pszName, GDAL_OF_VECTOR | ((bUpdate) ? GDAL_OF_UPDATE : 0),
     132             :                    nullptr, nullptr, nullptr);
     133         178 :     if (hDS != nullptr && pahDriverList != nullptr)
     134           0 :         *pahDriverList =
     135           0 :             reinterpret_cast<OGRSFDriverH>(GDALGetDatasetDriver(hDS));
     136             : 
     137         178 :     return reinterpret_cast<OGRDataSourceH>(hDS);
     138             : }
     139             : 
     140             : /************************************************************************/
     141             : /*                           OGROpenShared()                            */
     142             : /************************************************************************/
     143             : 
     144             : /**
     145             :   \brief Open a file / data source with one of the registered drivers if not
     146             :   already opened, or increment reference count of already opened data source
     147             :   previously opened with OGROpenShared()
     148             : 
     149             :   This function loops through all the drivers registered with the driver
     150             :   manager trying each until one succeeds with the given data source.
     151             : 
     152             :   If this function fails, CPLGetLastErrorMsg() can be used to check if there
     153             :   is an error message explaining why.
     154             : 
     155             :   NOTE: It is *NOT* safe to cast the returned handle to
     156             :   OGRDataSource*. If a C++ object is needed, the handle should be cast to GDALDataset*.
     157             :   Similarly, the returned OGRSFDriverH handle should be cast to GDALDriver*, and
     158             :   *NOT* OGRSFDriver*.
     159             : 
     160             :   @deprecated Use GDALOpenEx()
     161             : 
     162             :   @param pszName the name of the file, or data source to open.
     163             :   @param bUpdate FALSE for read-only access (the default) or TRUE for
     164             :          read-write access.
     165             :   @param pahDriverList if non-NULL, this argument will be updated with a
     166             :          pointer to the driver which was used to open the data source.
     167             : 
     168             :   @return NULL on error or if the pass name is not supported by this driver,
     169             :   otherwise a handle to a GDALDataset.  This GDALDataset should be
     170             :   closed by deleting the object when it is no longer needed.
     171             : 
     172             :   Example:
     173             : 
     174             :   \code{.cpp}
     175             :     OGRDataSourceH  hDS;
     176             :     OGRSFDriverH        *pahDriver;
     177             : 
     178             :     hDS = OGROpenShared( "polygon.shp", 0, pahDriver );
     179             :     if( hDS == NULL )
     180             :     {
     181             :         return;
     182             :     }
     183             : 
     184             :     ... use the data source ...
     185             : 
     186             :     OGRReleaseDataSource( hDS );
     187             :   \endcode
     188             : 
     189             : */
     190          21 : OGRDataSourceH OGROpenShared(const char *pszName, int bUpdate,
     191             :                              OGRSFDriverH *pahDriverList)
     192             : 
     193             : {
     194          21 :     VALIDATE_POINTER1(pszName, "OGROpenShared", nullptr);
     195             : 
     196          21 :     GDALDatasetH hDS = GDALOpenEx(
     197             :         pszName,
     198             :         GDAL_OF_VECTOR | ((bUpdate) ? GDAL_OF_UPDATE : 0) | GDAL_OF_SHARED,
     199             :         nullptr, nullptr, nullptr);
     200          21 :     if (hDS != nullptr && pahDriverList != nullptr)
     201           0 :         *pahDriverList =
     202           0 :             reinterpret_cast<OGRSFDriverH>(GDALGetDatasetDriver(hDS));
     203          21 :     return reinterpret_cast<OGRDataSourceH>(hDS);
     204             : }
     205             : 
     206             : /************************************************************************/
     207             : /*                        OGRReleaseDataSource()                        */
     208             : /************************************************************************/
     209             : 
     210             : /**
     211             : \brief Drop a reference to this datasource, and if the reference count drops to zero close (destroy) the datasource.
     212             : 
     213             : Internally this actually calls
     214             : the OGRSFDriverRegistrar::ReleaseDataSource() method.  This method is
     215             : essentially a convenient alias.
     216             : 
     217             : @deprecated Use GDALClose()
     218             : 
     219             : @param hDS handle to the data source to release
     220             : 
     221             : @return OGRERR_NONE on success or an error code.
     222             : */
     223             : 
     224          12 : OGRErr OGRReleaseDataSource(OGRDataSourceH hDS)
     225             : 
     226             : {
     227          12 :     VALIDATE_POINTER1(hDS, "OGRReleaseDataSource", OGRERR_INVALID_HANDLE);
     228             : 
     229          12 :     GDALClose(reinterpret_cast<GDALDatasetH>(hDS));
     230             : 
     231          12 :     return OGRERR_NONE;
     232             : }
     233             : 
     234             : //! @cond Doxygen_Suppress
     235             : /************************************************************************/
     236             : /*                           GetOpenDSCount()                           */
     237             : /************************************************************************/
     238             : 
     239           0 : int OGRSFDriverRegistrar::GetOpenDSCount()
     240             : {
     241           0 :     CPLError(CE_Failure, CPLE_AppDefined, "Stub implementation");
     242           0 :     return 0;
     243             : }
     244             : 
     245             : /************************************************************************/
     246             : /*                         OGRGetOpenDSCount()                          */
     247             : /************************************************************************/
     248             : 
     249           0 : int OGRGetOpenDSCount()
     250             : 
     251             : {
     252           0 :     return OGRSFDriverRegistrar::GetRegistrar()->GetOpenDSCount();
     253             : }
     254             : 
     255             : /************************************************************************/
     256             : /*                             GetOpenDS()                              */
     257             : /************************************************************************/
     258             : 
     259           1 : OGRDataSource *OGRSFDriverRegistrar::GetOpenDS(CPL_UNUSED int iDS)
     260             : {
     261           1 :     CPLError(CE_Failure, CPLE_AppDefined, "Stub implementation");
     262           1 :     return nullptr;
     263             : }
     264             : 
     265             : /************************************************************************/
     266             : /*                            OGRGetOpenDS()                            */
     267             : /************************************************************************/
     268             : 
     269           1 : OGRDataSourceH OGRGetOpenDS(int iDS)
     270             : 
     271             : {
     272             :     return reinterpret_cast<OGRDataSourceH>(
     273           1 :         OGRSFDriverRegistrar::GetRegistrar()->GetOpenDS(iDS));
     274             : }
     275             : 
     276             : /************************************************************************/
     277             : /*                          OpenWithDriverArg()                         */
     278             : /************************************************************************/
     279             : 
     280           0 : GDALDataset *OGRSFDriverRegistrar::OpenWithDriverArg(GDALDriver *poDriver,
     281             :                                                      GDALOpenInfo *poOpenInfo)
     282             : {
     283           0 :     OGRDataSource *poDS = reinterpret_cast<OGRDataSource *>(
     284             :         reinterpret_cast<OGRSFDriver *>(poDriver)->Open(
     285           0 :             poOpenInfo->pszFilename, poOpenInfo->eAccess == GA_Update));
     286           0 :     if (poDS != nullptr)
     287           0 :         poDS->SetDescription(poDS->GetName());
     288           0 :     return poDS;
     289             : }
     290             : 
     291             : /************************************************************************/
     292             : /*                          CreateVectorOnly()                          */
     293             : /************************************************************************/
     294             : 
     295           0 : GDALDataset *OGRSFDriverRegistrar::CreateVectorOnly(GDALDriver *poDriver,
     296             :                                                     const char *pszName,
     297             :                                                     char **papszOptions)
     298             : {
     299           0 :     OGRDataSource *poDS = reinterpret_cast<OGRDataSource *>(
     300             :         reinterpret_cast<OGRSFDriver *>(poDriver)->CreateDataSource(
     301           0 :             pszName, papszOptions));
     302           0 :     if (poDS != nullptr && poDS->GetName() != nullptr)
     303           0 :         poDS->SetDescription(poDS->GetName());
     304           0 :     return poDS;
     305             : }
     306             : 
     307             : /************************************************************************/
     308             : /*                          DeleteDataSource()                          */
     309             : /************************************************************************/
     310             : 
     311           0 : CPLErr OGRSFDriverRegistrar::DeleteDataSource(GDALDriver *poDriver,
     312             :                                               const char *pszName)
     313             : {
     314           0 :     if (reinterpret_cast<OGRSFDriver *>(poDriver)->DeleteDataSource(pszName) ==
     315             :         OGRERR_NONE)
     316           0 :         return CE_None;
     317             :     else
     318           0 :         return CE_Failure;
     319             : }
     320             : 
     321             : /************************************************************************/
     322             : /*                           RegisterDriver()                           */
     323             : /************************************************************************/
     324             : 
     325           0 : void OGRSFDriverRegistrar::RegisterDriver(OGRSFDriver *poDriver)
     326             : 
     327             : {
     328             :     GDALDriver *poGDALDriver =
     329           0 :         GDALDriver::FromHandle(GDALGetDriverByName(poDriver->GetName()));
     330           0 :     if (poGDALDriver == nullptr)
     331             :     {
     332           0 :         poDriver->SetDescription(poDriver->GetName());
     333           0 :         poDriver->SetMetadataItem("OGR_DRIVER", "YES");
     334             : 
     335           0 :         if (poDriver->GetMetadataItem(GDAL_DMD_LONGNAME) == nullptr)
     336           0 :             poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, poDriver->GetName());
     337             : 
     338           0 :         poDriver->pfnOpenWithDriverArg = OpenWithDriverArg;
     339             : 
     340           0 :         if (poDriver->TestCapability(ODrCCreateDataSource))
     341             :         {
     342           0 :             poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES");
     343           0 :             poDriver->pfnCreateVectorOnly = CreateVectorOnly;
     344             :         }
     345           0 :         if (poDriver->TestCapability(ODrCDeleteDataSource))
     346             :         {
     347           0 :             poDriver->pfnDeleteDataSource = DeleteDataSource;
     348             :         }
     349             : 
     350           0 :         poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");
     351             : 
     352           0 :         GetGDALDriverManager()->RegisterDriver(poDriver);
     353             :     }
     354             :     else
     355             :     {
     356           0 :         if (poGDALDriver->GetMetadataItem("OGR_DRIVER") == nullptr)
     357             :         {
     358           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     359             :                      "A non OGR driver is registered with the same name: %s",
     360           0 :                      poDriver->GetName());
     361             :         }
     362           0 :         delete poDriver;
     363             :     }
     364           0 : }
     365             : 
     366             : /************************************************************************/
     367             : /*                         OGRRegisterDriver()                          */
     368             : /************************************************************************/
     369             : 
     370           0 : void OGRRegisterDriver(OGRSFDriverH hDriver)
     371             : 
     372             : {
     373           0 :     VALIDATE_POINTER0(hDriver, "OGRRegisterDriver");
     374             : 
     375           0 :     GetGDALDriverManager()->RegisterDriver(GDALDriver::FromHandle(hDriver));
     376             : }
     377             : 
     378             : /************************************************************************/
     379             : /*                        OGRDeregisterDriver()                         */
     380             : /************************************************************************/
     381             : 
     382           0 : void OGRDeregisterDriver(OGRSFDriverH hDriver)
     383             : 
     384             : {
     385           0 :     VALIDATE_POINTER0(hDriver, "OGRDeregisterDriver");
     386             : 
     387           0 :     GetGDALDriverManager()->DeregisterDriver(GDALDriver::FromHandle(hDriver));
     388             : }
     389             : 
     390             : /************************************************************************/
     391             : /*                           GetDriverCount()                           */
     392             : /************************************************************************/
     393             : 
     394         313 : int OGRSFDriverRegistrar::GetDriverCount()
     395             : 
     396             : {
     397             :     /* We must be careful only to return drivers that are actual OGRSFDriver* */
     398         313 :     GDALDriverManager *poDriverManager = GetGDALDriverManager();
     399         313 :     int nTotal = poDriverManager->GetDriverCount();
     400         313 :     int nOGRDriverCount = 0;
     401       69026 :     for (int i = 0; i < nTotal; i++)
     402             :     {
     403       68713 :         GDALDriver *poDriver = poDriverManager->GetDriver(i);
     404       68713 :         if (poDriver->GetMetadataItem(GDAL_DCAP_VECTOR) != nullptr)
     405       27104 :             nOGRDriverCount++;
     406             :     }
     407         313 :     return nOGRDriverCount;
     408             : }
     409             : 
     410             : //! @endcond
     411             : 
     412             : /************************************************************************/
     413             : /*                         OGRGetDriverCount()                          */
     414             : /************************************************************************/
     415             : 
     416             : /**
     417             :   \brief Fetch the number of registered drivers.
     418             : 
     419             :   @deprecated Use GDALGetDriverCount()
     420             : 
     421             :   @return the drivers count.
     422             : 
     423             : */
     424         313 : int OGRGetDriverCount()
     425             : 
     426             : {
     427         313 :     return OGRSFDriverRegistrar::GetRegistrar()->GetDriverCount();
     428             : }
     429             : 
     430             : /************************************************************************/
     431             : /*                             GetDriver()                              */
     432             : /************************************************************************/
     433             : 
     434             : //! @cond Doxygen_Suppress
     435           0 : GDALDriver *OGRSFDriverRegistrar::GetDriver(int iDriver)
     436             : 
     437             : {
     438             :     /* We must be careful only to return drivers that are actual OGRSFDriver* */
     439           0 :     GDALDriverManager *poDriverManager = GetGDALDriverManager();
     440           0 :     int nTotal = poDriverManager->GetDriverCount();
     441           0 :     int nOGRDriverCount = 0;
     442           0 :     for (int i = 0; i < nTotal; i++)
     443             :     {
     444           0 :         GDALDriver *poDriver = poDriverManager->GetDriver(i);
     445           0 :         if (poDriver->GetMetadataItem(GDAL_DCAP_VECTOR) != nullptr)
     446             :         {
     447           0 :             if (nOGRDriverCount == iDriver)
     448           0 :                 return poDriver;
     449           0 :             nOGRDriverCount++;
     450             :         }
     451             :     }
     452           0 :     return nullptr;
     453             : }
     454             : 
     455             : //! @endcond
     456             : 
     457             : /************************************************************************/
     458             : /*                            OGRGetDriver()                            */
     459             : /************************************************************************/
     460             : 
     461             : /**
     462             :   \brief Fetch the indicated driver.
     463             : 
     464             :   NOTE: It is *NOT* safe to cast the returned handle to
     465             :   OGRSFDriver*. If a C++ object is needed, the handle should be cast to GDALDriver*.
     466             : 
     467             :   @deprecated Use GDALGetDriver()
     468             : 
     469             :   @param iDriver the driver index, from 0 to GetDriverCount()-1.
     470             : 
     471             :   @return handle to the driver, or NULL if iDriver is out of range.
     472             : 
     473             : */
     474             : 
     475           0 : OGRSFDriverH OGRGetDriver(int iDriver)
     476             : 
     477             : {
     478             :     return reinterpret_cast<OGRSFDriverH>(
     479           0 :         OGRSFDriverRegistrar::GetRegistrar()->GetDriver(iDriver));
     480             : }
     481             : 
     482             : /************************************************************************/
     483             : /*                          GetDriverByName()                           */
     484             : /************************************************************************/
     485             : 
     486             : //! @cond Doxygen_Suppress
     487        2799 : GDALDriver *OGRSFDriverRegistrar::GetDriverByName(const char *pszName)
     488             : 
     489             : {
     490        2799 :     GDALDriverManager *poDriverManager = GetGDALDriverManager();
     491             :     GDALDriver *poGDALDriver =
     492        2799 :         poDriverManager->GetDriverByName(CPLSPrintf("OGR_%s", pszName));
     493        2799 :     if (poGDALDriver == nullptr)
     494        2797 :         poGDALDriver = poDriverManager->GetDriverByName(pszName);
     495        5585 :     if (poGDALDriver == nullptr ||
     496        2786 :         poGDALDriver->GetMetadataItem(GDAL_DCAP_VECTOR) == nullptr)
     497          13 :         return nullptr;
     498        2786 :     return poGDALDriver;
     499             : }
     500             : 
     501             : //! @endcond
     502             : 
     503             : /************************************************************************/
     504             : /*                         OGRGetDriverByName()                         */
     505             : /************************************************************************/
     506             : 
     507             : /**
     508             :   \brief Fetch the indicated driver.
     509             : 
     510             :   NOTE: It is *NOT* safe to cast the returned handle to
     511             :   OGRSFDriver*. If a C++ object is needed, the handle should be cast to GDALDriver*.
     512             : 
     513             :   @deprecated Use GDALGetDriverByName()
     514             : 
     515             :   @param pszName the driver name
     516             : 
     517             :   @return the driver, or NULL if no driver with that name is found
     518             : */
     519             : 
     520        2793 : OGRSFDriverH OGRGetDriverByName(const char *pszName)
     521             : 
     522             : {
     523        2793 :     VALIDATE_POINTER1(pszName, "OGRGetDriverByName", nullptr);
     524             : 
     525             :     return reinterpret_cast<OGRSFDriverH>(
     526        2793 :         OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszName));
     527             : }

Generated by: LCOV version 1.14