LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/openfilegdb - ogropenfilegdbdriver.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 56 64 87.5 %
Date: 2024-11-21 22:18:42 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implements Open FileGDB OGR driver.
       5             :  * Author:   Even Rouault, <even dot rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2014, Even Rouault <even dot rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "cpl_port.h"
      14             : #include "ogr_openfilegdb.h"
      15             : #include "ogropenfilegdbdrivercore.h"
      16             : 
      17             : #include <cstddef>
      18             : #include <cstring>
      19             : 
      20             : #include "cpl_conv.h"
      21             : #include "cpl_vsi.h"
      22             : #include "gdal.h"
      23             : #include "gdal_priv.h"
      24             : #include "ogr_core.h"
      25             : 
      26             : // g++ -O2 -Wall -Wextra -g -shared -fPIC ogr/ogrsf_frmts/openfilegdb/*.cpp
      27             : // -o ogr_OpenFileGDB.so -Iport -Igcore -Iogr -Iogr/ogrsf_frmts
      28             : // -Iogr/ogrsf_frmts/mem -Iogr/ogrsf_frmts/openfilegdb -L. -lgdal
      29             : 
      30             : extern "C" void RegisterOGROpenFileGDB();
      31             : 
      32             : /************************************************************************/
      33             : /*                                Open()                                */
      34             : /************************************************************************/
      35             : 
      36         603 : static GDALDataset *OGROpenFileGDBDriverOpen(GDALOpenInfo *poOpenInfo)
      37             : 
      38             : {
      39         603 :     const char *pszFilename = poOpenInfo->pszFilename;
      40             : #ifdef FOR_FUSIL
      41             :     CPLString osOrigFilename(pszFilename);
      42             : #endif
      43         603 :     if (OGROpenFileGDBDriverIdentify(poOpenInfo, pszFilename) ==
      44             :         GDAL_IDENTIFY_FALSE)
      45           0 :         return nullptr;
      46             : 
      47             : #ifdef FOR_FUSIL
      48             :     const char *pszSrcDir = CPLGetConfigOption("FUSIL_SRC_DIR", NULL);
      49             :     if (pszSrcDir != NULL && VSIStatL(osOrigFilename, &stat) == 0 &&
      50             :         VSI_ISREG(stat.st_mode))
      51             :     {
      52             :         /* Copy all files from FUSIL_SRC_DIR to directory of pszFilename */
      53             :         /* except pszFilename itself */
      54             :         CPLString osSave(pszFilename);
      55             :         char **papszFiles = VSIReadDir(pszSrcDir);
      56             :         for (int i = 0; papszFiles[i] != NULL; i++)
      57             :         {
      58             :             if (strcmp(papszFiles[i], CPLGetFilename(osOrigFilename)) != 0)
      59             :             {
      60             :                 CPLCopyFile(CPLFormFilename(CPLGetPath(osOrigFilename),
      61             :                                             papszFiles[i], NULL),
      62             :                             CPLFormFilename(pszSrcDir, papszFiles[i], NULL));
      63             :             }
      64             :         }
      65             :         CSLDestroy(papszFiles);
      66             :         pszFilename = CPLFormFilename("", osSave.c_str(), NULL);
      67             :     }
      68             : #endif
      69             : 
      70             : #ifdef DEBUG
      71             :     /* For AFL, so that .cur_input is detected as the archive filename */
      72        1320 :     if (poOpenInfo->fpL != nullptr &&
      73         717 :         !STARTS_WITH(poOpenInfo->pszFilename, "/vsitar/") &&
      74         114 :         EQUAL(CPLGetFilename(poOpenInfo->pszFilename), ".cur_input"))
      75             :     {
      76             :         GDALOpenInfo oOpenInfo(
      77           2 :             (CPLString("/vsitar/") + poOpenInfo->pszFilename).c_str(),
      78           3 :             poOpenInfo->nOpenFlags);
      79           1 :         oOpenInfo.papszOpenOptions = poOpenInfo->papszOpenOptions;
      80           1 :         return OGROpenFileGDBDriverOpen(&oOpenInfo);
      81             :     }
      82             : #endif
      83             : 
      84        1204 :     auto poDS = std::make_unique<OGROpenFileGDBDataSource>();
      85         602 :     bool bRetryFileGDB = false;
      86         602 :     if (poDS->Open(poOpenInfo, bRetryFileGDB))
      87             :     {
      88         540 :         if (poDS->GetSubdatasets().size() == 2)
      89             :         {
      90             :             // If there is a single raster dataset, open it right away.
      91             :             GDALOpenInfo oOpenInfo(
      92           7 :                 poDS->GetSubdatasets().FetchNameValue("SUBDATASET_1_NAME"),
      93          21 :                 poOpenInfo->nOpenFlags);
      94           7 :             poDS = std::make_unique<OGROpenFileGDBDataSource>();
      95           7 :             if (poDS->Open(&oOpenInfo, bRetryFileGDB))
      96             :             {
      97           7 :                 poDS->SetDescription(poOpenInfo->pszFilename);
      98             :             }
      99             :             else
     100             :             {
     101           0 :                 poDS.reset();
     102             :             }
     103             :         }
     104         540 :         return poDS.release();
     105             :     }
     106          62 :     else if (bRetryFileGDB)
     107             :     {
     108           2 :         auto poDriver = GetGDALDriverManager()->GetDriverByName("FileGDB");
     109           2 :         if (poDriver)
     110             :         {
     111           4 :             GDALOpenInfo oOpenInfo(pszFilename, poOpenInfo->nOpenFlags);
     112           4 :             CPLStringList aosOpenOptions;
     113           2 :             aosOpenOptions.SetNameValue("@MAY_USE_OPENFILEGDB", "NO");
     114           2 :             oOpenInfo.papszOpenOptions = aosOpenOptions.List();
     115           2 :             return poDriver->Open(&oOpenInfo, false);
     116             :         }
     117             :     }
     118             : 
     119          60 :     return nullptr;
     120             : }
     121             : 
     122             : /************************************************************************/
     123             : /*                              Create()                                */
     124             : /************************************************************************/
     125             : 
     126         281 : static GDALDataset *OGROpenFileGDBDriverCreate(const char *pszName, int nXSize,
     127             :                                                int nYSize, int nBands,
     128             :                                                GDALDataType eType,
     129             :                                                char ** /* papszOptions*/)
     130             : 
     131             : {
     132         281 :     if (!(nXSize == 0 && nYSize == 0 && nBands == 0 && eType == GDT_Unknown))
     133             :     {
     134          50 :         CPLError(CE_Failure, CPLE_NotSupported,
     135             :                  "OpenFileGDB::Create(): only vector datasets supported");
     136          50 :         return nullptr;
     137             :     }
     138             : 
     139         462 :     auto poDS = std::make_unique<OGROpenFileGDBDataSource>();
     140         231 :     if (!poDS->Create(pszName))
     141           3 :         return nullptr;
     142         228 :     return poDS.release();
     143             : }
     144             : 
     145             : /************************************************************************/
     146             : /*                     OGROpenFileGDBDriverDelete()                     */
     147             : /************************************************************************/
     148             : 
     149          30 : static CPLErr OGROpenFileGDBDriverDelete(const char *pszFilename)
     150             : {
     151          60 :     CPLStringList aosFiles(VSIReadDir(pszFilename));
     152          30 :     if (aosFiles.empty())
     153           0 :         return CE_Failure;
     154             : 
     155         618 :     for (int i = 0; i < aosFiles.size(); ++i)
     156             :     {
     157         588 :         if (strcmp(aosFiles[i], ".") != 0 && strcmp(aosFiles[i], "..") != 0)
     158             :         {
     159             :             const std::string osFilename(
     160         586 :                 CPLFormFilename(pszFilename, aosFiles[i], nullptr));
     161         586 :             if (VSIUnlink(osFilename.c_str()) != 0)
     162             :             {
     163           0 :                 CPLError(CE_Failure, CPLE_FileIO, "Cannot delete %s",
     164             :                          osFilename.c_str());
     165           0 :                 return CE_Failure;
     166             :             }
     167             :         }
     168             :     }
     169          30 :     if (VSIRmdir(pszFilename) != 0)
     170             :     {
     171           0 :         CPLError(CE_Failure, CPLE_FileIO, "Cannot delete %s", pszFilename);
     172           0 :         return CE_Failure;
     173             :     }
     174             : 
     175          30 :     return CE_None;
     176             : }
     177             : 
     178             : /***********************************************************************/
     179             : /*                       RegisterOGROpenFileGDB()                      */
     180             : /***********************************************************************/
     181             : 
     182        1595 : void RegisterOGROpenFileGDB()
     183             : 
     184             : {
     185        1595 :     if (!GDAL_CHECK_VERSION("OGR OpenFileGDB"))
     186           0 :         return;
     187             : 
     188        1595 :     if (GDALGetDriverByName(DRIVER_NAME) != nullptr)
     189         302 :         return;
     190             : 
     191        1293 :     GDALDriver *poDriver = new GDALDriver();
     192        1293 :     OGROpenFileGDBDriverSetCommonMetadata(poDriver);
     193             : 
     194        1293 :     poDriver->pfnOpen = OGROpenFileGDBDriverOpen;
     195        1293 :     poDriver->pfnCreate = OGROpenFileGDBDriverCreate;
     196        1293 :     poDriver->pfnDelete = OGROpenFileGDBDriverDelete;
     197             : 
     198        1293 :     GetGDALDriverManager()->RegisterDriver(poDriver);
     199             : }

Generated by: LCOV version 1.14