LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/gpsbabel - ogrgpsbabelwritedatasource.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 52 88 59.1 %
Date: 2024-11-21 22:18:42 Functions: 6 9 66.7 %

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

Generated by: LCOV version 1.14