LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/gpsbabel - ogrgpsbabelwritedatasource.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 51 87 58.6 %
Date: 2025-07-13 21:00:45 Functions: 5 8 62.5 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implements OGRGPSBabelWriteDataSource class.
       5             :  * Author:   Even Rouault, <even dot rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2010-2013, Even Rouault <even dot rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include <cstring>
      14             : #include "cpl_conv.h"
      15             : #include "cpl_string.h"
      16             : #include "cpl_error.h"
      17             : #include "cpl_spawn.h"
      18             : 
      19             : #include "ogr_gpsbabel.h"
      20             : 
      21             : /************************************************************************/
      22             : /*                    OGRGPSBabelWriteDataSource()                      */
      23             : /************************************************************************/
      24             : 
      25             : OGRGPSBabelWriteDataSource::OGRGPSBabelWriteDataSource() = default;
      26             : 
      27             : /************************************************************************/
      28             : /*                  ~OGRGPSBabelWriteDataSource()                       */
      29             : /************************************************************************/
      30             : 
      31           2 : OGRGPSBabelWriteDataSource::~OGRGPSBabelWriteDataSource()
      32             : 
      33             : {
      34           1 :     if (poGPXDS)
      35           1 :         GDALClose(poGPXDS);
      36             : 
      37           1 :     Convert();
      38             : 
      39           1 :     CPLFree(pszGPSBabelDriverName);
      40           1 :     CPLFree(pszFilename);
      41           2 : }
      42             : 
      43             : /************************************************************************/
      44             : /*                                Convert()                             */
      45             : /************************************************************************/
      46             : 
      47           1 : bool OGRGPSBabelWriteDataSource::Convert()
      48             : {
      49           1 :     int nRet = -1;
      50           2 :     if (!osTmpFileName.empty() && pszFilename != nullptr &&
      51           1 :         pszGPSBabelDriverName != nullptr)
      52             :     {
      53           1 :         if (OGRGPSBabelDataSource::IsSpecialFile(pszFilename))
      54             :         {
      55             :             /* Special file : don't try to open it */
      56           0 :             VSILFILE *tmpfp = VSIFOpenL(osTmpFileName.c_str(), "rb");
      57           0 :             if (tmpfp)
      58             :             {
      59           0 :                 const char *const argv[] = {"gpsbabel",
      60             :                                             "-i",
      61             :                                             "gpx",
      62             :                                             "-f",
      63             :                                             "-",
      64             :                                             "-o",
      65           0 :                                             pszGPSBabelDriverName,
      66             :                                             "-F",
      67           0 :                                             pszFilename,
      68           0 :                                             nullptr};
      69           0 :                 nRet = CPLSpawn(argv, tmpfp, nullptr, TRUE);
      70             : 
      71           0 :                 VSIFCloseL(tmpfp);
      72           0 :                 tmpfp = nullptr;
      73             :             }
      74             :         }
      75             :         else
      76             :         {
      77           1 :             VSILFILE *fp = VSIFOpenL(pszFilename, "wb");
      78           1 :             if (fp == nullptr)
      79             :             {
      80           0 :                 CPLError(CE_Failure, CPLE_AppDefined, "Cannot open file %s",
      81             :                          pszFilename);
      82             :             }
      83             :             else
      84             :             {
      85           1 :                 VSILFILE *tmpfp = VSIFOpenL(osTmpFileName.c_str(), "rb");
      86           1 :                 if (tmpfp)
      87             :                 {
      88           1 :                     const char *const argv[] = {"gpsbabel",
      89             :                                                 "-i",
      90             :                                                 "gpx",
      91             :                                                 "-f",
      92             :                                                 "-",
      93             :                                                 "-o",
      94           1 :                                                 pszGPSBabelDriverName,
      95             :                                                 "-F",
      96             :                                                 "-",
      97           1 :                                                 nullptr};
      98           1 :                     nRet = CPLSpawn(argv, tmpfp, fp, TRUE);
      99             : 
     100           1 :                     VSIFCloseL(tmpfp);
     101           1 :                     tmpfp = nullptr;
     102             :                 }
     103             : 
     104           1 :                 VSIFCloseL(fp);
     105           1 :                 fp = nullptr;
     106             :             }
     107             :         }
     108             : 
     109           1 :         VSIUnlink(osTmpFileName.c_str());
     110           1 :         osTmpFileName = "";
     111             :     }
     112             : 
     113           1 :     return nRet == 0;
     114             : }
     115             : 
     116             : /************************************************************************/
     117             : /*                                 Create()                             */
     118             : /************************************************************************/
     119             : 
     120           1 : int OGRGPSBabelWriteDataSource::Create(const char *pszNameIn,
     121             :                                        char **papszOptions)
     122             : {
     123             :     GDALDriver *poGPXDriver =
     124           1 :         OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName("GPX");
     125           1 :     if (poGPXDriver == nullptr)
     126             :     {
     127           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     128             :                  "GPX driver is necessary for GPSBabel write support");
     129           0 :         return FALSE;
     130             :     }
     131             : 
     132           1 :     if (!STARTS_WITH_CI(pszNameIn, "GPSBABEL:"))
     133             :     {
     134             :         const char *pszOptionGPSBabelDriverName =
     135           0 :             CSLFetchNameValue(papszOptions, "GPSBABEL_DRIVER");
     136           0 :         if (pszOptionGPSBabelDriverName != nullptr)
     137           0 :             pszGPSBabelDriverName = CPLStrdup(pszOptionGPSBabelDriverName);
     138             :         else
     139             :         {
     140           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     141             :                      "GPSBABEL_DRIVER dataset creation option expected");
     142           0 :             return FALSE;
     143             :         }
     144             : 
     145           0 :         pszFilename = CPLStrdup(pszNameIn);
     146             :     }
     147             :     else
     148             :     {
     149           1 :         const char *pszSep = strchr(pszNameIn + 9, ':');
     150           1 :         if (pszSep == nullptr)
     151             :         {
     152           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     153             :                      "Wrong syntax. Expected GPSBabel:driver_name[,options]*:"
     154             :                      "file_name");
     155           0 :             return FALSE;
     156             :         }
     157             : 
     158           1 :         pszGPSBabelDriverName = CPLStrdup(pszNameIn + 9);
     159           1 :         char *nextColon = strchr(pszGPSBabelDriverName, ':');
     160           1 :         if (nextColon)
     161           1 :             *nextColon = 0;
     162             : 
     163           1 :         pszFilename = CPLStrdup(pszSep + 1);
     164             :     }
     165             : 
     166             :     /* A bit of validation to avoid command line injection */
     167           1 :     if (!OGRGPSBabelDataSource::IsValidDriverName(pszGPSBabelDriverName))
     168           0 :         return FALSE;
     169             : 
     170             :     const char *pszOptionUseTempFile =
     171           1 :         CSLFetchNameValue(papszOptions, "USE_TEMPFILE");
     172           1 :     if (pszOptionUseTempFile == nullptr)
     173           1 :         pszOptionUseTempFile = CPLGetConfigOption("USE_TEMPFILE", nullptr);
     174           1 :     if (pszOptionUseTempFile && CPLTestBool(pszOptionUseTempFile))
     175           0 :         osTmpFileName = CPLGenerateTempFilenameSafe(nullptr);
     176             :     else
     177           1 :         osTmpFileName = VSIMemGenerateHiddenFilename("gpsbabel");
     178             : 
     179           1 :     poGPXDS = poGPXDriver->Create(osTmpFileName.c_str(), 0, 0, 0, GDT_Unknown,
     180             :                                   papszOptions);
     181           1 :     if (poGPXDS == nullptr)
     182           0 :         return FALSE;
     183             : 
     184           1 :     return TRUE;
     185             : }
     186             : 
     187             : /************************************************************************/
     188             : /*                           ICreateLayer()                             */
     189             : /************************************************************************/
     190             : 
     191           1 : OGRLayer *OGRGPSBabelWriteDataSource::ICreateLayer(
     192             :     const char *pszLayerName, const OGRGeomFieldDefn *poGeomFieldDefn,
     193             :     CSLConstList papszOptions)
     194             : {
     195           1 :     if (poGPXDS)
     196           1 :         return poGPXDS->CreateLayer(pszLayerName, poGeomFieldDefn,
     197           1 :                                     papszOptions);
     198           0 :     return nullptr;
     199             : }
     200             : 
     201             : /************************************************************************/
     202             : /*                           TestCapability()                           */
     203             : /************************************************************************/
     204             : 
     205           0 : int OGRGPSBabelWriteDataSource::TestCapability(const char *pszCap)
     206             : 
     207             : {
     208           0 :     if (EQUAL(pszCap, ODsCCreateLayer))
     209           0 :         return TRUE;
     210             : 
     211           0 :     return FALSE;
     212             : }
     213             : 
     214             : /************************************************************************/
     215             : /*                              GetLayer()                              */
     216             : /************************************************************************/
     217             : 
     218           0 : OGRLayer *OGRGPSBabelWriteDataSource::GetLayer(int iLayer)
     219             : 
     220             : {
     221           0 :     if (poGPXDS)
     222           0 :         return poGPXDS->GetLayer(iLayer);
     223             : 
     224           0 :     return nullptr;
     225             : }
     226             : 
     227             : /************************************************************************/
     228             : /*                         GetLayerCount()                              */
     229             : /************************************************************************/
     230             : 
     231           0 : int OGRGPSBabelWriteDataSource::GetLayerCount()
     232             : 
     233             : {
     234           0 :     if (poGPXDS)
     235           0 :         return poGPXDS->GetLayerCount();
     236             : 
     237           0 :     return 0;
     238             : }

Generated by: LCOV version 1.14