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-05-02 22:57:13 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             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice shall be included
      18             :  * in all copies or substantial portions of the Software.
      19             :  *
      20             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26             :  * DEALINGS IN THE SOFTWARE.
      27             :  ****************************************************************************/
      28             : 
      29             : #include "cpl_port.h"
      30             : #include "ogr_openfilegdb.h"
      31             : #include "ogropenfilegdbdrivercore.h"
      32             : 
      33             : #include <cstddef>
      34             : #include <cstring>
      35             : 
      36             : #include "cpl_conv.h"
      37             : #include "cpl_vsi.h"
      38             : #include "gdal.h"
      39             : #include "gdal_priv.h"
      40             : #include "ogr_core.h"
      41             : 
      42             : // g++ -O2 -Wall -Wextra -g -shared -fPIC ogr/ogrsf_frmts/openfilegdb/*.cpp
      43             : // -o ogr_OpenFileGDB.so -Iport -Igcore -Iogr -Iogr/ogrsf_frmts
      44             : // -Iogr/ogrsf_frmts/mem -Iogr/ogrsf_frmts/openfilegdb -L. -lgdal
      45             : 
      46             : extern "C" void RegisterOGROpenFileGDB();
      47             : 
      48             : /************************************************************************/
      49             : /*                                Open()                                */
      50             : /************************************************************************/
      51             : 
      52         552 : static GDALDataset *OGROpenFileGDBDriverOpen(GDALOpenInfo *poOpenInfo)
      53             : 
      54             : {
      55         552 :     const char *pszFilename = poOpenInfo->pszFilename;
      56             : #ifdef FOR_FUSIL
      57             :     CPLString osOrigFilename(pszFilename);
      58             : #endif
      59         552 :     if (OGROpenFileGDBDriverIdentify(poOpenInfo, pszFilename) ==
      60             :         GDAL_IDENTIFY_FALSE)
      61           0 :         return nullptr;
      62             : 
      63             : #ifdef FOR_FUSIL
      64             :     const char *pszSrcDir = CPLGetConfigOption("FUSIL_SRC_DIR", NULL);
      65             :     if (pszSrcDir != NULL && VSIStatL(osOrigFilename, &stat) == 0 &&
      66             :         VSI_ISREG(stat.st_mode))
      67             :     {
      68             :         /* Copy all files from FUSIL_SRC_DIR to directory of pszFilename */
      69             :         /* except pszFilename itself */
      70             :         CPLString osSave(pszFilename);
      71             :         char **papszFiles = VSIReadDir(pszSrcDir);
      72             :         for (int i = 0; papszFiles[i] != NULL; i++)
      73             :         {
      74             :             if (strcmp(papszFiles[i], CPLGetFilename(osOrigFilename)) != 0)
      75             :             {
      76             :                 CPLCopyFile(CPLFormFilename(CPLGetPath(osOrigFilename),
      77             :                                             papszFiles[i], NULL),
      78             :                             CPLFormFilename(pszSrcDir, papszFiles[i], NULL));
      79             :             }
      80             :         }
      81             :         CSLDestroy(papszFiles);
      82             :         pszFilename = CPLFormFilename("", osSave.c_str(), NULL);
      83             :     }
      84             : #endif
      85             : 
      86             : #ifdef DEBUG
      87             :     /* For AFL, so that .cur_input is detected as the archive filename */
      88        1210 :     if (poOpenInfo->fpL != nullptr &&
      89         658 :         !STARTS_WITH(poOpenInfo->pszFilename, "/vsitar/") &&
      90         106 :         EQUAL(CPLGetFilename(poOpenInfo->pszFilename), ".cur_input"))
      91             :     {
      92             :         GDALOpenInfo oOpenInfo(
      93           2 :             (CPLString("/vsitar/") + poOpenInfo->pszFilename).c_str(),
      94           3 :             poOpenInfo->nOpenFlags);
      95           1 :         oOpenInfo.papszOpenOptions = poOpenInfo->papszOpenOptions;
      96           1 :         return OGROpenFileGDBDriverOpen(&oOpenInfo);
      97             :     }
      98             : #endif
      99             : 
     100        1102 :     auto poDS = std::make_unique<OGROpenFileGDBDataSource>();
     101         551 :     bool bRetryFileGDB = false;
     102         551 :     if (poDS->Open(poOpenInfo, bRetryFileGDB))
     103             :     {
     104         490 :         if (poDS->GetSubdatasets().size() == 2)
     105             :         {
     106             :             // If there is a single raster dataset, open it right away.
     107             :             GDALOpenInfo oOpenInfo(
     108           7 :                 poDS->GetSubdatasets().FetchNameValue("SUBDATASET_1_NAME"),
     109          21 :                 poOpenInfo->nOpenFlags);
     110           7 :             poDS = std::make_unique<OGROpenFileGDBDataSource>();
     111           7 :             if (poDS->Open(&oOpenInfo, bRetryFileGDB))
     112             :             {
     113           7 :                 poDS->SetDescription(poOpenInfo->pszFilename);
     114             :             }
     115             :             else
     116             :             {
     117           0 :                 poDS.reset();
     118             :             }
     119             :         }
     120         490 :         return poDS.release();
     121             :     }
     122          61 :     else if (bRetryFileGDB)
     123             :     {
     124           2 :         auto poDriver = GetGDALDriverManager()->GetDriverByName("FileGDB");
     125           2 :         if (poDriver)
     126             :         {
     127           4 :             GDALOpenInfo oOpenInfo(pszFilename, poOpenInfo->nOpenFlags);
     128           4 :             CPLStringList aosOpenOptions;
     129           2 :             aosOpenOptions.SetNameValue("@MAY_USE_OPENFILEGDB", "NO");
     130           2 :             oOpenInfo.papszOpenOptions = aosOpenOptions.List();
     131           2 :             return poDriver->Open(&oOpenInfo, false);
     132             :         }
     133             :     }
     134             : 
     135          59 :     return nullptr;
     136             : }
     137             : 
     138             : /************************************************************************/
     139             : /*                              Create()                                */
     140             : /************************************************************************/
     141             : 
     142         278 : static GDALDataset *OGROpenFileGDBDriverCreate(const char *pszName, int nXSize,
     143             :                                                int nYSize, int nBands,
     144             :                                                GDALDataType eType,
     145             :                                                char ** /* papszOptions*/)
     146             : 
     147             : {
     148         278 :     if (!(nXSize == 0 && nYSize == 0 && nBands == 0 && eType == GDT_Unknown))
     149             :     {
     150          50 :         CPLError(CE_Failure, CPLE_NotSupported,
     151             :                  "OpenFileGDB::Create(): only vector datasets supported");
     152          50 :         return nullptr;
     153             :     }
     154             : 
     155         456 :     auto poDS = std::make_unique<OGROpenFileGDBDataSource>();
     156         228 :     if (!poDS->Create(pszName))
     157           3 :         return nullptr;
     158         225 :     return poDS.release();
     159             : }
     160             : 
     161             : /************************************************************************/
     162             : /*                     OGROpenFileGDBDriverDelete()                     */
     163             : /************************************************************************/
     164             : 
     165          30 : static CPLErr OGROpenFileGDBDriverDelete(const char *pszFilename)
     166             : {
     167          60 :     CPLStringList aosFiles(VSIReadDir(pszFilename));
     168          30 :     if (aosFiles.empty())
     169           0 :         return CE_Failure;
     170             : 
     171         618 :     for (int i = 0; i < aosFiles.size(); ++i)
     172             :     {
     173         588 :         if (strcmp(aosFiles[i], ".") != 0 && strcmp(aosFiles[i], "..") != 0)
     174             :         {
     175             :             const std::string osFilename(
     176         586 :                 CPLFormFilename(pszFilename, aosFiles[i], nullptr));
     177         586 :             if (VSIUnlink(osFilename.c_str()) != 0)
     178             :             {
     179           0 :                 CPLError(CE_Failure, CPLE_FileIO, "Cannot delete %s",
     180             :                          osFilename.c_str());
     181           0 :                 return CE_Failure;
     182             :             }
     183             :         }
     184             :     }
     185          30 :     if (VSIRmdir(pszFilename) != 0)
     186             :     {
     187           0 :         CPLError(CE_Failure, CPLE_FileIO, "Cannot delete %s", pszFilename);
     188           0 :         return CE_Failure;
     189             :     }
     190             : 
     191          30 :     return CE_None;
     192             : }
     193             : 
     194             : /***********************************************************************/
     195             : /*                       RegisterOGROpenFileGDB()                      */
     196             : /***********************************************************************/
     197             : 
     198        1512 : void RegisterOGROpenFileGDB()
     199             : 
     200             : {
     201        1512 :     if (!GDAL_CHECK_VERSION("OGR OpenFileGDB"))
     202           0 :         return;
     203             : 
     204        1512 :     if (GDALGetDriverByName(DRIVER_NAME) != nullptr)
     205         295 :         return;
     206             : 
     207        1217 :     GDALDriver *poDriver = new GDALDriver();
     208        1217 :     OGROpenFileGDBDriverSetCommonMetadata(poDriver);
     209             : 
     210        1217 :     poDriver->pfnOpen = OGROpenFileGDBDriverOpen;
     211        1217 :     poDriver->pfnCreate = OGROpenFileGDBDriverCreate;
     212        1217 :     poDriver->pfnDelete = OGROpenFileGDBDriverDelete;
     213             : 
     214        1217 :     GetGDALDriverManager()->RegisterDriver(poDriver);
     215             : }

Generated by: LCOV version 1.14