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-05-03 15:49:35 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             :  * 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 "gdalsubdatasetinfo.h"
      30             : #include "gdal_priv.h"
      31             : #include <algorithm>
      32             : #include <stdexcept>
      33             : 
      34             : /************************************************************************/
      35             : /*                     Subdataset informational functions               */
      36             : /************************************************************************/
      37             : 
      38        1079 : GDALSubdatasetInfoH GDALGetSubdatasetInfo(const char *pszFileName)
      39             : {
      40             :     // Iterate all drivers
      41        1079 :     GDALDriverManager *poDM_ = GetGDALDriverManager();
      42        1079 :     const int nDriverCount = poDM_->GetDriverCount();
      43      237181 :     for (int iDriver = 0; iDriver < nDriverCount; ++iDriver)
      44             :     {
      45      236195 :         GDALDriver *poDriver = poDM_->GetDriver(iDriver);
      46      236195 :         if (!poDriver->pfnGetSubdatasetInfoFunc)
      47             :         {
      48      229020 :             continue;
      49             :         }
      50             :         const char *pszDMDSubdatasets =
      51        7175 :             GDALGetMetadataItem(poDriver, GDAL_DMD_SUBDATASETS, nullptr);
      52        7175 :         if (!pszDMDSubdatasets || !CPLTestBool(pszDMDSubdatasets))
      53             :         {
      54           0 :             continue;
      55             :         }
      56             : 
      57             :         GDALSubdatasetInfo *poGetSubdatasetInfo =
      58        7175 :             poDriver->pfnGetSubdatasetInfoFunc(pszFileName);
      59             : 
      60        7175 :         if (!poGetSubdatasetInfo)
      61             :         {
      62        7082 :             continue;
      63             :         }
      64             : 
      65          93 :         return static_cast<GDALSubdatasetInfoH>(poGetSubdatasetInfo);
      66             :     }
      67         986 :     return nullptr;
      68             : }
      69             : 
      70             : /************************************************************************/
      71             : /*                       GDALDestroySubdatasetInfo()                    */
      72             : /************************************************************************/
      73             : 
      74             : /**
      75             :  * \brief Destroys subdataset info.
      76             :  *
      77             :  * This function is the same as the C++ method GDALSubdatasetInfo::~GDALSubdatasetInfo()
      78             :  */
      79          93 : void GDALDestroySubdatasetInfo(GDALSubdatasetInfoH hInfo)
      80             : 
      81             : {
      82          93 :     delete hInfo;
      83          93 : }
      84             : 
      85          35 : char *GDALSubdatasetInfoGetPathComponent(GDALSubdatasetInfoH hInfo)
      86             : {
      87          35 :     return CPLStrdup(hInfo->GetPathComponent().c_str());
      88             : }
      89             : 
      90          61 : char *GDALSubdatasetInfoGetSubdatasetComponent(GDALSubdatasetInfoH hInfo)
      91             : {
      92          61 :     return CPLStrdup(hInfo->GetSubdatasetComponent().c_str());
      93             : }
      94             : 
      95          21 : char *GDALSubdatasetInfoModifyPathComponent(GDALSubdatasetInfoH hInfo,
      96             :                                             const char *pszNewFileName)
      97             : {
      98          21 :     return CPLStrdup(hInfo->ModifyPathComponent(pszNewFileName).c_str());
      99             : }
     100             : 
     101         107 : GDALSubdatasetInfo::GDALSubdatasetInfo(const std::string &fileName)
     102             :     : m_fileName(fileName), m_pathComponent(), m_cleanedPathComponent(),
     103         107 :       m_subdatasetComponent(), m_driverPrefixComponent()
     104             : {
     105         107 : }
     106             : 
     107         152 : std::string GDALSubdatasetInfo::GetPathComponent() const
     108             : {
     109         152 :     init();
     110         152 :     return m_cleanedPathComponent;
     111             : }
     112             : 
     113             : std::string
     114          31 : GDALSubdatasetInfo::ModifyPathComponent(const std::string &newPathName) const
     115             : {
     116          31 :     init();
     117             : 
     118          62 :     std::string replaced{m_fileName};
     119             : 
     120             :     try
     121             :     {
     122          62 :         auto newPathName_{newPathName};
     123          31 :         if (m_isQuoted)
     124             :         {
     125          26 :             if (newPathName_.length() >= 2 && newPathName_.at(0) != '"' &&
     126          10 :                 newPathName_.at(newPathName_.length() - 1) != '"')
     127             :             {
     128          10 :                 newPathName_ = quote(newPathName_);
     129             :             }
     130             :         }
     131          31 :         replaced.replace(replaced.find(m_pathComponent),
     132          31 :                          m_pathComponent.length(), newPathName_);
     133             :     }
     134           0 :     catch (const std::out_of_range &)
     135             :     {
     136           0 :         return "";
     137             :     }
     138             : 
     139          31 :     return replaced;
     140             : }
     141             : 
     142         116 : std::string GDALSubdatasetInfo::GetSubdatasetComponent() const
     143             : {
     144         116 :     init();
     145         116 :     return m_subdatasetComponent;
     146             : }
     147             : 
     148             : //! @cond Doxygen_Suppress
     149          51 : std::string GDALSubdatasetInfo::unquote(const std::string &path)
     150             : {
     151          51 :     if (path.length() >= 2)
     152             :     {
     153          51 :         std::string cleanedPath{path};
     154         102 :         if (cleanedPath.at(0) == '"' &&
     155          51 :             cleanedPath.at(cleanedPath.length() - 1) == '"')
     156             :         {
     157          51 :             cleanedPath = cleanedPath.substr(1, cleanedPath.length() - 2);
     158          53 :             while (cleanedPath.find(R"(\")") != std::string::npos)
     159             :             {
     160           2 :                 const auto pos{cleanedPath.find(R"(\")")};
     161           2 :                 if (pos == 0 || cleanedPath.at(pos - 1) != '\\')
     162             :                 {
     163           2 :                     cleanedPath.erase(pos, 1);
     164             :                 }
     165             :             }
     166          51 :             return cleanedPath;
     167             :         }
     168             :     }
     169           0 :     return path;
     170             : }
     171             : 
     172          10 : std::string GDALSubdatasetInfo::quote(const std::string &path)
     173             : {
     174          20 :     std::string quotedPath{'"'};
     175         336 :     for (size_t i = 0; i < path.length(); ++i)
     176             :     {
     177         326 :         if (path.at(i) == '"')
     178             :         {
     179           0 :             quotedPath += R"(\")";
     180             :         }
     181             :         else
     182             :         {
     183         326 :             quotedPath += path.at(i);
     184             :         }
     185             :     }
     186          20 :     return quotedPath + '"';
     187             : }
     188             : 
     189         299 : void GDALSubdatasetInfo::init() const
     190             : {
     191         299 :     if (!m_initialized)
     192             :     {
     193         107 :         GDALSubdatasetInfo *this_ = const_cast<GDALSubdatasetInfo *>(this);
     194         107 :         this_->parseFileName();
     195         107 :         this_->m_isQuoted =
     196         158 :             m_pathComponent.length() >= 2 && m_pathComponent.at(0) == '"' &&
     197          51 :             m_pathComponent.at(m_pathComponent.length() - 1) == '"';
     198             :         this_->m_cleanedPathComponent =
     199         107 :             m_isQuoted ? unquote(m_pathComponent) : m_pathComponent;
     200         107 :         m_initialized = true;
     201             :     }
     202         299 : }
     203             : 
     204             : //! @endcond

Generated by: LCOV version 1.14