LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/geoconcept - ogrgeoconceptdriver.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 58 69 84.1 %
Date: 2025-01-18 12:42:00 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implements OGRGeoconceptDriver class.
       5             :  * Author:   Didier Richard, didier.richard@ign.fr
       6             :  * Language: C++
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2007,  Geoconcept and IGN
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "cpl_conv.h"
      15             : #include "cpl_string.h"
      16             : #include "ogrgeoconceptdatasource.h"
      17             : 
      18             : /************************************************************************/
      19             : /*                                Open()                                */
      20             : /************************************************************************/
      21             : 
      22       25031 : static GDALDataset *OGRGeoconceptDriverOpen(GDALOpenInfo *poOpenInfo)
      23             : 
      24             : {
      25       25031 :     const char *pszFilename = poOpenInfo->pszFilename;
      26             : #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
      27             :     /* -------------------------------------------------------------------- */
      28             :     /*      We will only consider .gxt and .txt files.                      */
      29             :     /* -------------------------------------------------------------------- */
      30       50062 :     const std::string osExtension = CPLGetExtensionSafe(pszFilename);
      31       50057 :     if (!EQUAL(osExtension.c_str(), "gxt") &&
      32       25026 :         !EQUAL(osExtension.c_str(), "txt"))
      33             :     {
      34       25015 :         return nullptr;
      35             :     }
      36             : #endif
      37             : 
      38          16 :     auto poDS = new OGRGeoconceptDataSource();
      39             : 
      40          16 :     if (!poDS->Open(pszFilename, true, poOpenInfo->eAccess == GA_Update))
      41             :     {
      42           8 :         delete poDS;
      43           8 :         return nullptr;
      44             :     }
      45           8 :     return poDS;
      46             : }
      47             : 
      48             : /************************************************************************/
      49             : /*                          CreateDataSource()                          */
      50             : /*                                                                      */
      51             : /* Options (-dsco) :                                                    */
      52             : /*   EXTENSION=GXT|TXT (default GXT)                                    */
      53             : /************************************************************************/
      54             : 
      55          18 : static GDALDataset *OGRGeoconceptDriverCreate(const char *pszName,
      56             :                                               int /* nXSize */,
      57             :                                               int /* nYSize */,
      58             :                                               int /* nBandCount */,
      59             :                                               GDALDataType, char **papszOptions)
      60             : 
      61             : {
      62             :     VSIStatBufL sStat;
      63             :     /* int bSingleNewFile = FALSE; */
      64             : 
      65          18 :     if (pszName == nullptr || strlen(pszName) == 0)
      66             :     {
      67           0 :         CPLError(CE_Failure, CPLE_AppDefined,
      68             :                  "Invalid datasource name (null or empty)");
      69           0 :         return nullptr;
      70             :     }
      71             : 
      72             :     /* -------------------------------------------------------------------- */
      73             :     /*      Is the target a valid existing directory?                       */
      74             :     /* -------------------------------------------------------------------- */
      75          18 :     if (VSIStatL(pszName, &sStat) == 0)
      76             :     {
      77           0 :         if (!VSI_ISDIR(sStat.st_mode))
      78             :         {
      79           0 :             CPLError(CE_Failure, CPLE_AppDefined,
      80             :                      "%s is not a valid existing directory.", pszName);
      81           0 :             return nullptr;
      82             :         }
      83             :     }
      84             : 
      85             :     /* -------------------------------------------------------------------- */
      86             :     /*      Does it end with the extension .gxt indicating the user likely  */
      87             :     /*      wants to create a single file set?                              */
      88             :     /* -------------------------------------------------------------------- */
      89          53 :     else if (EQUAL(CPLGetExtensionSafe(pszName).c_str(), "gxt") ||
      90          35 :              EQUAL(CPLGetExtensionSafe(pszName).c_str(), "txt"))
      91             :     {
      92             :         /* bSingleNewFile = TRUE; */
      93             :     }
      94             : 
      95             :     /* -------------------------------------------------------------------- */
      96             :     /*      Return a new OGRDataSource()                                    */
      97             :     /* -------------------------------------------------------------------- */
      98          18 :     OGRGeoconceptDataSource *poDS = new OGRGeoconceptDataSource();
      99          18 :     if (!poDS->Create(pszName, papszOptions))
     100             :     {
     101           1 :         delete poDS;
     102           1 :         return nullptr;
     103             :     }
     104          17 :     return poDS;
     105             : }
     106             : 
     107             : /************************************************************************/
     108             : /*                      OGRGeoconceptDriverDelete()                     */
     109             : /************************************************************************/
     110             : 
     111          16 : static CPLErr OGRGeoconceptDriverDelete(const char *pszDataSource)
     112             : 
     113             : {
     114             :     VSIStatBufL sStatBuf;
     115             :     static const char *const apszExtensions[] = {"gxt", "txt", "gct",
     116             :                                                  "gcm", "gcr", nullptr};
     117             : 
     118          16 :     if (VSIStatL(pszDataSource, &sStatBuf) != 0)
     119             :     {
     120           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     121             :                  "%s does not appear to be a file or directory.",
     122             :                  pszDataSource);
     123             : 
     124           0 :         return CE_Failure;
     125             :     }
     126             : 
     127          16 :     if (VSI_ISREG(sStatBuf.st_mode) &&
     128          16 :         (EQUAL(CPLGetExtensionSafe(pszDataSource).c_str(), "gxt") ||
     129          16 :          EQUAL(CPLGetExtensionSafe(pszDataSource).c_str(), "txt")))
     130             :     {
     131           0 :         for (int iExt = 0; apszExtensions[iExt] != nullptr; iExt++)
     132             :         {
     133             :             const std::string osFile =
     134           0 :                 CPLResetExtensionSafe(pszDataSource, apszExtensions[iExt]);
     135           0 :             if (VSIStatL(osFile.c_str(), &sStatBuf) == 0)
     136           0 :                 VSIUnlink(osFile.c_str());
     137             :         }
     138             :     }
     139          16 :     else if (VSI_ISDIR(sStatBuf.st_mode))
     140             :     {
     141          16 :         char **papszDirEntries = VSIReadDir(pszDataSource);
     142             : 
     143          32 :         for (int iFile = 0;
     144          32 :              papszDirEntries != nullptr && papszDirEntries[iFile] != nullptr;
     145             :              iFile++)
     146             :         {
     147          16 :             if (CSLFindString(
     148             :                     const_cast<char **>(apszExtensions),
     149          32 :                     CPLGetExtensionSafe(papszDirEntries[iFile]).c_str()) != -1)
     150             :             {
     151          16 :                 VSIUnlink(CPLFormFilenameSafe(pszDataSource,
     152          16 :                                               papszDirEntries[iFile], nullptr)
     153             :                               .c_str());
     154             :             }
     155             :         }
     156             : 
     157          16 :         CSLDestroy(papszDirEntries);
     158             : 
     159          16 :         VSIRmdir(pszDataSource);
     160             :     }
     161             : 
     162          16 :     return CE_None;
     163             : }
     164             : 
     165             : /************************************************************************/
     166             : /*                          RegisterOGRGeoconcept()                     */
     167             : /************************************************************************/
     168             : 
     169        1682 : void RegisterOGRGeoconcept()
     170             : 
     171             : {
     172        1682 :     if (GDALGetDriverByName("Geoconcept"))
     173         301 :         return;
     174             : 
     175        1381 :     GDALDriver *poDriver = new GDALDriver();
     176        1381 :     poDriver->SetDescription("Geoconcept");
     177        1381 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "Geoconcept");
     178        1381 :     poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");
     179        1381 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_LAYER, "YES");
     180        1381 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_FIELD, "YES");
     181        1381 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSIONS, "gxt txt");
     182        1381 :     poDriver->SetMetadataItem(GDAL_DCAP_Z_GEOMETRIES, "YES");
     183             : 
     184        1381 :     poDriver->SetMetadataItem(
     185             :         GDAL_DMD_CREATIONOPTIONLIST,
     186             :         "<CreationOptionList>"
     187             :         "  <Option name='EXTENSION' type='string-select' "
     188             :         "description='indicates the "
     189             :         "GeoConcept export file extension. TXT was used by earlier releases of "
     190             :         "GeoConcept. GXT is currently used.' default='GXT'>"
     191             :         "    <Value>GXT</Value>"
     192             :         "    <Value>TXT</Value>"
     193             :         "  </Option>"
     194             :         "  <Option name='CONFIG' type='string' description='path to the GCT "
     195             :         "file that "
     196             :         "describes the GeoConcept types definitions.'/>"
     197        1381 :         "</CreationOptionList>");
     198             : 
     199        1381 :     poDriver->SetMetadataItem(GDAL_DS_LAYER_CREATIONOPTIONLIST,
     200             :                               "<LayerCreationOptionList>"
     201             :                               "  <Option name='FEATURETYPE' type='string' "
     202             :                               "description='TYPE.SUBTYPE : "
     203             :                               "defines the feature to be created. The TYPE "
     204             :                               "corresponds to one of the Name "
     205             :                               "found in the GCT file for a type section. The "
     206             :                               "SUBTYPE corresponds to one of "
     207             :                               "the Name found in the GCT file for a sub-type "
     208             :                               "section within the previous "
     209             :                               "type section'/>"
     210        1381 :                               "</LayerCreationOptionList>");
     211        1381 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     212        1381 :     poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE");
     213             : 
     214        1381 :     poDriver->pfnOpen = OGRGeoconceptDriverOpen;
     215        1381 :     poDriver->pfnCreate = OGRGeoconceptDriverCreate;
     216        1381 :     poDriver->pfnDelete = OGRGeoconceptDriverDelete;
     217             : 
     218        1381 :     GetGDALDriverManager()->RegisterDriver(poDriver);
     219             : }

Generated by: LCOV version 1.14