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

Generated by: LCOV version 1.14