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

Generated by: LCOV version 1.14