LCOV - code coverage report
Current view: top level - gcore - gdalsubdatasetinfo.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 70 75 93.3 %
Date: 2024-11-21 22:18:42 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /***************************************************************************
       2             :   gdal_subdatasetinfo.cpp - GDALSubdatasetInfo
       3             : 
       4             :  ---------------------
       5             :  begin                : 21.7.2023
       6             :  copyright            : (C) 2023 by Alessndro Pasotti
       7             :  email                : elpaso@itopen.it
       8             :  ***************************************************************************
       9             :  *                                                                         *
      10             :  * SPDX-License-Identifier: MIT
      11             :  *                                                                         *
      12             :  ***************************************************************************/
      13             : #include "gdalsubdatasetinfo.h"
      14             : #include "gdal_priv.h"
      15             : #include <algorithm>
      16             : #include <stdexcept>
      17             : 
      18             : /************************************************************************/
      19             : /*                     Subdataset informational functions               */
      20             : /************************************************************************/
      21             : 
      22        2686 : GDALSubdatasetInfoH GDALGetSubdatasetInfo(const char *pszFileName)
      23             : {
      24             :     // Iterate all drivers
      25        2686 :     GDALDriverManager *poDM_ = GetGDALDriverManager();
      26        2686 :     const int nDriverCount = poDM_->GetDriverCount();
      27      627491 :     for (int iDriver = 0; iDriver < nDriverCount; ++iDriver)
      28             :     {
      29      624900 :         GDALDriver *poDriver = poDM_->GetDriver(iDriver);
      30      624900 :         if (!poDriver->pfnGetSubdatasetInfoFunc)
      31             :         {
      32      606486 :             continue;
      33             :         }
      34             :         const char *pszDMDSubdatasets =
      35       18414 :             GDALGetMetadataItem(poDriver, GDAL_DMD_SUBDATASETS, nullptr);
      36       18414 :         if (!pszDMDSubdatasets || !CPLTestBool(pszDMDSubdatasets))
      37             :         {
      38           0 :             continue;
      39             :         }
      40             : 
      41             :         GDALSubdatasetInfo *poGetSubdatasetInfo =
      42       18414 :             poDriver->pfnGetSubdatasetInfoFunc(pszFileName);
      43             : 
      44       18414 :         if (!poGetSubdatasetInfo)
      45             :         {
      46       18319 :             continue;
      47             :         }
      48             : 
      49          95 :         return static_cast<GDALSubdatasetInfoH>(poGetSubdatasetInfo);
      50             :     }
      51        2591 :     return nullptr;
      52             : }
      53             : 
      54             : /************************************************************************/
      55             : /*                       GDALDestroySubdatasetInfo()                    */
      56             : /************************************************************************/
      57             : 
      58             : /**
      59             :  * \brief Destroys subdataset info.
      60             :  *
      61             :  * This function is the same as the C++ method GDALSubdatasetInfo::~GDALSubdatasetInfo()
      62             :  */
      63          95 : void GDALDestroySubdatasetInfo(GDALSubdatasetInfoH hInfo)
      64             : 
      65             : {
      66          95 :     delete hInfo;
      67          95 : }
      68             : 
      69          35 : char *GDALSubdatasetInfoGetPathComponent(GDALSubdatasetInfoH hInfo)
      70             : {
      71          35 :     return CPLStrdup(hInfo->GetPathComponent().c_str());
      72             : }
      73             : 
      74          63 : char *GDALSubdatasetInfoGetSubdatasetComponent(GDALSubdatasetInfoH hInfo)
      75             : {
      76          63 :     return CPLStrdup(hInfo->GetSubdatasetComponent().c_str());
      77             : }
      78             : 
      79          21 : char *GDALSubdatasetInfoModifyPathComponent(GDALSubdatasetInfoH hInfo,
      80             :                                             const char *pszNewFileName)
      81             : {
      82          21 :     return CPLStrdup(hInfo->ModifyPathComponent(pszNewFileName).c_str());
      83             : }
      84             : 
      85         109 : GDALSubdatasetInfo::GDALSubdatasetInfo(const std::string &fileName)
      86             :     : m_fileName(fileName), m_pathComponent(), m_cleanedPathComponent(),
      87         109 :       m_subdatasetComponent(), m_driverPrefixComponent()
      88             : {
      89         109 : }
      90             : 
      91         154 : std::string GDALSubdatasetInfo::GetPathComponent() const
      92             : {
      93         154 :     init();
      94         154 :     return m_cleanedPathComponent;
      95             : }
      96             : 
      97             : std::string
      98          31 : GDALSubdatasetInfo::ModifyPathComponent(const std::string &newPathName) const
      99             : {
     100          31 :     init();
     101             : 
     102          62 :     std::string replaced{m_fileName};
     103             : 
     104             :     try
     105             :     {
     106          62 :         auto newPathName_{newPathName};
     107          31 :         if (m_isQuoted)
     108             :         {
     109          26 :             if (newPathName_.length() >= 2 && newPathName_.at(0) != '"' &&
     110          10 :                 newPathName_.at(newPathName_.length() - 1) != '"')
     111             :             {
     112          10 :                 newPathName_ = quote(newPathName_);
     113             :             }
     114             :         }
     115          31 :         replaced.replace(replaced.find(m_pathComponent),
     116          31 :                          m_pathComponent.length(), newPathName_);
     117             :     }
     118           0 :     catch (const std::out_of_range &)
     119             :     {
     120           0 :         return "";
     121             :     }
     122             : 
     123          31 :     return replaced;
     124             : }
     125             : 
     126         118 : std::string GDALSubdatasetInfo::GetSubdatasetComponent() const
     127             : {
     128         118 :     init();
     129         118 :     return m_subdatasetComponent;
     130             : }
     131             : 
     132             : //! @cond Doxygen_Suppress
     133          53 : std::string GDALSubdatasetInfo::unquote(const std::string &path)
     134             : {
     135          53 :     if (path.length() >= 2)
     136             :     {
     137          53 :         std::string cleanedPath{path};
     138         106 :         if (cleanedPath.at(0) == '"' &&
     139          53 :             cleanedPath.at(cleanedPath.length() - 1) == '"')
     140             :         {
     141          53 :             cleanedPath = cleanedPath.substr(1, cleanedPath.length() - 2);
     142          55 :             while (cleanedPath.find(R"(\")") != std::string::npos)
     143             :             {
     144           2 :                 const auto pos{cleanedPath.find(R"(\")")};
     145           2 :                 if (pos == 0 || cleanedPath.at(pos - 1) != '\\')
     146             :                 {
     147           2 :                     cleanedPath.erase(pos, 1);
     148             :                 }
     149             :             }
     150          53 :             return cleanedPath;
     151             :         }
     152             :     }
     153           0 :     return path;
     154             : }
     155             : 
     156          10 : std::string GDALSubdatasetInfo::quote(const std::string &path)
     157             : {
     158          20 :     std::string quotedPath{'"'};
     159         336 :     for (size_t i = 0; i < path.length(); ++i)
     160             :     {
     161         326 :         if (path.at(i) == '"')
     162             :         {
     163           0 :             quotedPath += R"(\")";
     164             :         }
     165             :         else
     166             :         {
     167         326 :             quotedPath += path.at(i);
     168             :         }
     169             :     }
     170          20 :     return quotedPath + '"';
     171             : }
     172             : 
     173         303 : void GDALSubdatasetInfo::init() const
     174             : {
     175         303 :     if (!m_initialized)
     176             :     {
     177         109 :         GDALSubdatasetInfo *this_ = const_cast<GDALSubdatasetInfo *>(this);
     178         109 :         this_->parseFileName();
     179         109 :         this_->m_isQuoted =
     180         162 :             m_pathComponent.length() >= 2 && m_pathComponent.at(0) == '"' &&
     181          53 :             m_pathComponent.at(m_pathComponent.length() - 1) == '"';
     182             :         this_->m_cleanedPathComponent =
     183         109 :             m_isQuoted ? unquote(m_pathComponent) : m_pathComponent;
     184         109 :         m_initialized = true;
     185             :     }
     186         303 : }
     187             : 
     188             : //! @endcond

Generated by: LCOV version 1.14