LCOV - code coverage report
Current view: top level - frmts/sdts - sdtscatd.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 77 100 77.0 %
Date: 2024-05-04 12:52:34 Functions: 7 9 77.8 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  SDTS Translator
       4             :  * Purpose:  Implementation of SDTS_CATD and SDTS_CATDEntry classes for
       5             :  *           reading CATD files.
       6             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 1999, Frank Warmerdam
      10             :  *
      11             :  * Permission is hereby granted, free of charge, to any person obtaining a
      12             :  * copy of this software and associated documentation files (the "Software"),
      13             :  * to deal in the Software without restriction, including without limitation
      14             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15             :  * and/or sell copies of the Software, and to permit persons to whom the
      16             :  * Software is furnished to do so, subject to the following conditions:
      17             :  *
      18             :  * The above copyright notice and this permission notice shall be included
      19             :  * in all copies or substantial portions of the Software.
      20             :  *
      21             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27             :  * DEALINGS IN THE SOFTWARE.
      28             :  ****************************************************************************/
      29             : 
      30             : #include "sdts_al.h"
      31             : 
      32             : #include <set>
      33             : 
      34             : /************************************************************************/
      35             : /* ==================================================================== */
      36             : /*                            SDTS_CATDEntry                            */
      37             : /*                                                                      */
      38             : /*      This class is for internal use of the SDTS_CATD class only,     */
      39             : /*      and represents one entry in the directory ... a reference       */
      40             : /*      to another module file.                                         */
      41             : /* ==================================================================== */
      42             : /************************************************************************/
      43             : 
      44             : class SDTS_CATDEntry
      45             : 
      46             : {
      47             :   public:
      48             :     char *pszModule;
      49             :     char *pszType;
      50             :     char *pszFile;
      51             :     char *pszExternalFlag;
      52             : 
      53             :     char *pszFullPath;
      54             : };
      55             : 
      56             : /************************************************************************/
      57             : /* ==================================================================== */
      58             : /*                             SDTS_CATD                                */
      59             : /* ==================================================================== */
      60             : /************************************************************************/
      61             : 
      62             : /************************************************************************/
      63             : /*                             SDTS_CATD()                              */
      64             : /************************************************************************/
      65             : 
      66          52 : SDTS_CATD::SDTS_CATD()
      67          52 :     : pszPrefixPath(nullptr), nEntries(0), papoEntries(nullptr)
      68             : {
      69          52 : }
      70             : 
      71             : /************************************************************************/
      72             : /*                             ~SDTS_CATD()                             */
      73             : /************************************************************************/
      74             : 
      75         104 : SDTS_CATD::~SDTS_CATD()
      76             : {
      77         112 :     for (int i = 0; i < nEntries; i++)
      78             :     {
      79          60 :         CPLFree(papoEntries[i]->pszModule);
      80          60 :         CPLFree(papoEntries[i]->pszType);
      81          60 :         CPLFree(papoEntries[i]->pszFile);
      82          60 :         CPLFree(papoEntries[i]->pszExternalFlag);
      83          60 :         CPLFree(papoEntries[i]->pszFullPath);
      84          60 :         delete papoEntries[i];
      85             :     }
      86             : 
      87          52 :     CPLFree(papoEntries);
      88          52 :     CPLFree(pszPrefixPath);
      89          52 : }
      90             : 
      91             : /************************************************************************/
      92             : /*                                Read()                                */
      93             : /*                                                                      */
      94             : /*      Read the named file to initialize this structure.               */
      95             : /************************************************************************/
      96             : 
      97          52 : int SDTS_CATD::Read(const char *pszFilename)
      98             : 
      99             : {
     100             :     /* -------------------------------------------------------------------- */
     101             :     /*      Open the file.                                                  */
     102             :     /* -------------------------------------------------------------------- */
     103         104 :     DDFModule oCATDFile;
     104          52 :     if (!oCATDFile.Open(pszFilename))
     105           0 :         return FALSE;
     106             : 
     107          52 :     CPLErrorReset();  // Clear any ADRG "unrecognized data_struct_code" errors.
     108             : 
     109             :     /* -------------------------------------------------------------------- */
     110             :     /*      Does this file have a CATD field?  If not, it isn't an SDTS     */
     111             :     /*      record and we won't even try reading the first record for       */
     112             :     /*      fear it will we a huge honking ADRG data record or something.   */
     113             :     /* -------------------------------------------------------------------- */
     114          52 :     if (oCATDFile.FindFieldDefn("CATD") == nullptr)
     115          49 :         return FALSE;
     116             : 
     117             :     /* -------------------------------------------------------------------- */
     118             :     /*      Strip off the filename, and keep the path prefix.               */
     119             :     /* -------------------------------------------------------------------- */
     120           3 :     pszPrefixPath = CPLStrdup(pszFilename);
     121           3 :     int i = static_cast<int>(strlen(pszPrefixPath)) - 1;
     122          39 :     for (; i > 0; i--)
     123             :     {
     124          39 :         if (pszPrefixPath[i] == '\\' || pszPrefixPath[i] == '/')
     125             :         {
     126           3 :             pszPrefixPath[i] = '\0';
     127           3 :             break;
     128             :         }
     129             :     }
     130             : 
     131           3 :     if (i <= 0)
     132             :     {
     133           0 :         strcpy(pszPrefixPath, ".");
     134             :     }
     135             : 
     136             :     /* ==================================================================== */
     137             :     /*      Loop reading CATD records, and adding to our list of entries    */
     138             :     /*      for each.                                                       */
     139             :     /* ==================================================================== */
     140           3 :     DDFRecord *poRecord = nullptr;
     141           3 :     int nIters = 0;
     142           3 :     std::set<std::string> aoSetFiles;
     143          63 :     while ((poRecord = oCATDFile.ReadRecord()) != nullptr && nIters < 1000)
     144             :     {
     145          60 :         nIters++;
     146             : 
     147             :         /* --------------------------------------------------------------------
     148             :          */
     149             :         /*      Verify that we have a proper CATD record. */
     150             :         /* --------------------------------------------------------------------
     151             :          */
     152          60 :         if (poRecord->GetStringSubfield("CATD", 0, "MODN", 0) == nullptr)
     153           0 :             continue;
     154             : 
     155             :         /* --------------------------------------------------------------------
     156             :          */
     157             :         /*      Create a new entry, and get the module and file name. */
     158             :         /* --------------------------------------------------------------------
     159             :          */
     160          60 :         SDTS_CATDEntry *poEntry = new SDTS_CATDEntry;
     161             : 
     162          60 :         poEntry->pszModule =
     163          60 :             CPLStrdup(poRecord->GetStringSubfield("CATD", 0, "NAME", 0));
     164          60 :         poEntry->pszFile =
     165          60 :             CPLStrdup(poRecord->GetStringSubfield("CATD", 0, "FILE", 0));
     166          60 :         poEntry->pszExternalFlag =
     167          60 :             CPLStrdup(poRecord->GetStringSubfield("CATD", 0, "EXTR", 0));
     168          60 :         poEntry->pszType =
     169          60 :             CPLStrdup(poRecord->GetStringSubfield("CATD", 0, "TYPE", 0));
     170             : 
     171          60 :         if (poEntry->pszModule[0] == '\0' || poEntry->pszFile[0] == '\0' ||
     172             :             // Exclude following one for performance reasons in oss-fuzz
     173         180 :             (poEntry->pszFile[0] == '/' && poEntry->pszFile[1] == '\0') ||
     174         120 :             aoSetFiles.find(poEntry->pszFile) != aoSetFiles.end())
     175             :         {
     176           0 :             CPLFree(poEntry->pszModule);
     177           0 :             CPLFree(poEntry->pszFile);
     178           0 :             CPLFree(poEntry->pszExternalFlag);
     179           0 :             CPLFree(poEntry->pszType);
     180           0 :             delete poEntry;
     181           0 :             continue;
     182             :         }
     183          60 :         aoSetFiles.insert(poEntry->pszFile);
     184             : 
     185             :         /* --------------------------------------------------------------------
     186             :          */
     187             :         /*      Create a full path to the file. */
     188             :         /* --------------------------------------------------------------------
     189             :          */
     190          60 :         poEntry->pszFullPath = CPLStrdup(
     191          60 :             CPLFormCIFilename(pszPrefixPath, poEntry->pszFile, nullptr));
     192             : 
     193             :         /* --------------------------------------------------------------------
     194             :          */
     195             :         /*      Add the entry to the list. */
     196             :         /* --------------------------------------------------------------------
     197             :          */
     198         120 :         papoEntries = reinterpret_cast<SDTS_CATDEntry **>(
     199          60 :             CPLRealloc(papoEntries, sizeof(void *) * ++nEntries));
     200          60 :         papoEntries[nEntries - 1] = poEntry;
     201             :     }
     202             : 
     203           3 :     return nEntries > 0;
     204             : }
     205             : 
     206             : /************************************************************************/
     207             : /*                         GetModuleFilePath()                          */
     208             : /************************************************************************/
     209             : 
     210          28 : const char *SDTS_CATD::GetModuleFilePath(const char *pszModule) const
     211             : 
     212             : {
     213         188 :     for (int i = 0; i < nEntries; i++)
     214             :     {
     215         188 :         if (EQUAL(papoEntries[i]->pszModule, pszModule))
     216          28 :             return papoEntries[i]->pszFullPath;
     217             :     }
     218             : 
     219           0 :     return nullptr;
     220             : }
     221             : 
     222             : /************************************************************************/
     223             : /*                           GetEntryModule()                           */
     224             : /************************************************************************/
     225             : 
     226          34 : const char *SDTS_CATD::GetEntryModule(int iEntry) const
     227             : 
     228             : {
     229          34 :     if (iEntry < 0 || iEntry >= nEntries)
     230           0 :         return nullptr;
     231             : 
     232          34 :     return papoEntries[iEntry]->pszModule;
     233             : }
     234             : 
     235             : /************************************************************************/
     236             : /*                          GetEntryTypeDesc()                          */
     237             : /************************************************************************/
     238             : 
     239             : /**
     240             :  * Fetch the type description of a module in the catalog.
     241             :  *
     242             :  * @param iEntry The module index within the CATD catalog.  A number from
     243             :  * zero to GetEntryCount()-1.
     244             :  *
     245             :  * @return A pointer to an internal string with the type description for
     246             :  * this module.  This is from the CATD file (subfield TYPE of field CATD),
     247             :  * and will be something like "Attribute Primary        ".
     248             :  */
     249             : 
     250           0 : const char *SDTS_CATD::GetEntryTypeDesc(int iEntry) const
     251             : 
     252             : {
     253           0 :     if (iEntry < 0 || iEntry >= nEntries)
     254           0 :         return nullptr;
     255             : 
     256           0 :     return papoEntries[iEntry]->pszType;
     257             : }
     258             : 
     259             : /************************************************************************/
     260             : /*                            GetEntryType()                            */
     261             : /************************************************************************/
     262             : 
     263             : /**
     264             :  * Fetch the enumerated type of a module in the catalog.
     265             :  *
     266             :  * @param iEntry The module index within the CATD catalog.  A number from
     267             :  * zero to GetEntryCount()-1.
     268             :  *
     269             :  * @return A value from the SDTSLayerType enumeration indicating the type of
     270             :  * the module, and indicating the corresponding type of reader.<p>
     271             :  *
     272             :  * <ul>
     273             :  * <li> SLTPoint: Read with SDTSPointReader, underlying type of
     274             :  * <tt>Point-Node</tt>.
     275             :  * <li> SLTLine: Read with SDTSLineReader, underlying type of
     276             :  * <tt>Line</tt>.
     277             :  * <li> SLTAttr: Read with SDTSAttrReader, underlying type of
     278             :  * <tt>Attribute Primary</tt> or <tt>Attribute Secondary</tt>.
     279             :  * <li> SLTPolygon: Read with SDTSPolygonReader, underlying type of
     280             :  * <tt>Polygon</tt>.
     281             :  * </ul>
     282             :  */
     283             : 
     284        1281 : SDTSLayerType SDTS_CATD::GetEntryType(int iEntry) const
     285             : 
     286             : {
     287        1281 :     if (iEntry < 0 || iEntry >= nEntries)
     288           0 :         return SLTUnknown;
     289             : 
     290        1281 :     else if (STARTS_WITH_CI(papoEntries[iEntry]->pszType, "Attribute Primary"))
     291         600 :         return SLTAttr;
     292             : 
     293         681 :     else if (STARTS_WITH_CI(papoEntries[iEntry]->pszType,
     294             :                             "Attribute Secondary"))
     295           0 :         return SLTAttr;
     296             : 
     297         681 :     else if (EQUAL(papoEntries[iEntry]->pszType, "Line") ||
     298         681 :              STARTS_WITH_CI(papoEntries[iEntry]->pszType, "Line "))
     299          93 :         return SLTLine;
     300             : 
     301         588 :     else if (STARTS_WITH_CI(papoEntries[iEntry]->pszType, "Point-Node"))
     302         411 :         return SLTPoint;
     303             : 
     304         177 :     else if (STARTS_WITH_CI(papoEntries[iEntry]->pszType, "Polygon"))
     305         121 :         return SLTPoly;
     306             : 
     307          56 :     else if (STARTS_WITH_CI(papoEntries[iEntry]->pszType, "Cell"))
     308           6 :         return SLTRaster;
     309             : 
     310             :     else
     311          50 :         return SLTUnknown;
     312             : }
     313             : 
     314             : /************************************************************************/
     315             : /*                       SetEntryTypeUnknown()                          */
     316             : /************************************************************************/
     317             : 
     318           0 : void SDTS_CATD::SetEntryTypeUnknown(int iEntry)
     319             : {
     320           0 :     if (iEntry >= 0 && iEntry < nEntries)
     321             :     {
     322           0 :         CPLFree(papoEntries[iEntry]->pszType);
     323           0 :         papoEntries[iEntry]->pszType = CPLStrdup("Unknown");
     324             :     }
     325           0 : }
     326             : 
     327             : /************************************************************************/
     328             : /*                          GetEntryFilePath()                          */
     329             : /************************************************************************/
     330             : 
     331             : /**
     332             :  * Fetch the full filename of the requested module.
     333             :  *
     334             :  * @param iEntry The module index within the CATD catalog.  A number from
     335             :  * zero to GetEntryCount()-1.
     336             :  *
     337             :  * @return A pointer to an internal string containing the filename.  This
     338             :  * string should not be altered, or freed by the application.
     339             :  */
     340             : 
     341           8 : const char *SDTS_CATD::GetEntryFilePath(int iEntry) const
     342             : 
     343             : {
     344           8 :     if (iEntry < 0 || iEntry >= nEntries)
     345           0 :         return nullptr;
     346             : 
     347           8 :     return papoEntries[iEntry]->pszFullPath;
     348             : }

Generated by: LCOV version 1.14