LCOV - code coverage report
Current view: top level - frmts/sdts - sdtslib.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 75 86 87.2 %
Date: 2024-05-04 12:52:34 Functions: 5 7 71.4 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  SDTS Translator
       4             :  * Purpose:  Various utility functions that apply to all SDTS profiles.
       5             :  *           SDTSModId, and SDTSFeature methods.
       6             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 1999, Frank Warmerdam
      10             :  * Copyright (c) 2009-2013, Even Rouault <even dot rouault at spatialys.com>
      11             :  *
      12             :  * Permission is hereby granted, free of charge, to any person obtaining a
      13             :  * copy of this software and associated documentation files (the "Software"),
      14             :  * to deal in the Software without restriction, including without limitation
      15             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16             :  * and/or sell copies of the Software, and to permit persons to whom the
      17             :  * Software is furnished to do so, subject to the following conditions:
      18             :  *
      19             :  * The above copyright notice and this permission notice shall be included
      20             :  * in all copies or substantial portions of the Software.
      21             :  *
      22             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28             :  * DEALINGS IN THE SOFTWARE.
      29             :  ****************************************************************************/
      30             : 
      31             : #include "sdts_al.h"
      32             : #include "cpl_string.h"
      33             : 
      34             : #include <set>
      35             : 
      36             : /************************************************************************/
      37             : /*                            SDTSFeature()                             */
      38             : /************************************************************************/
      39             : 
      40         572 : SDTSFeature::SDTSFeature() : nAttributes(0), paoATID(nullptr)
      41             : {
      42         572 : }
      43             : 
      44             : /************************************************************************/
      45             : /*                       SDTSFeature::ApplyATID()                       */
      46             : /************************************************************************/
      47             : 
      48          12 : void SDTSFeature::ApplyATID(DDFField *poField)
      49             : 
      50             : {
      51          12 :     DDFSubfieldDefn *poMODN = poField->GetFieldDefn()->FindSubfieldDefn("MODN");
      52          12 :     if (poMODN == nullptr)
      53             :     {
      54             :         // CPLAssert( false );
      55           0 :         return;
      56             :     }
      57             : 
      58          12 :     bool bUsualFormat = poMODN->GetWidth() == 4;
      59          12 :     const int nRepeatCount = poField->GetRepeatCount();
      60          24 :     for (int iRepeat = 0; iRepeat < nRepeatCount; iRepeat++)
      61             :     {
      62          12 :         paoATID = reinterpret_cast<SDTSModId *>(
      63          12 :             CPLRealloc(paoATID, sizeof(SDTSModId) * (nAttributes + 1)));
      64             : 
      65          12 :         SDTSModId *poModId = paoATID + nAttributes;
      66          12 :         *poModId = SDTSModId();
      67             : 
      68          12 :         if (bUsualFormat)
      69             :         {
      70             :             const char *pabyData =
      71          12 :                 poField->GetSubfieldData(poMODN, nullptr, iRepeat);
      72          12 :             if (pabyData == nullptr || strlen(pabyData) < 5)
      73           0 :                 return;
      74             : 
      75          12 :             memcpy(poModId->szModule, pabyData, 4);
      76          12 :             poModId->szModule[4] = '\0';
      77          12 :             poModId->nRecord = atoi(pabyData + 4);
      78          12 :             poModId->szOBRP[0] = '\0';
      79             :         }
      80             :         else
      81             :         {
      82           0 :             poModId->Set(poField);
      83             :         }
      84             : 
      85          12 :         nAttributes++;
      86             :     }
      87             : }
      88             : 
      89             : /************************************************************************/
      90             : /*                            ~SDTSFeature()                            */
      91             : /************************************************************************/
      92             : 
      93        1144 : SDTSFeature::~SDTSFeature()
      94             : 
      95             : {
      96         572 :     CPLFree(paoATID);
      97         572 :     paoATID = nullptr;
      98         572 : }
      99             : 
     100             : /************************************************************************/
     101             : /*                           SDTSModId::Set()                           */
     102             : /*                                                                      */
     103             : /*      Set a module from a field.  We depend on our pre-knowledge      */
     104             : /*      of the data layout to fetch more efficiently.                   */
     105             : /************************************************************************/
     106             : 
     107         827 : int SDTSModId::Set(DDFField *poField)
     108             : 
     109             : {
     110         827 :     const char *pachData = poField->GetData();
     111         827 :     DDFFieldDefn *poDefn = poField->GetFieldDefn();
     112             : 
     113        1654 :     if (poDefn->GetSubfieldCount() >= 2 &&
     114         827 :         poDefn->GetSubfield(0)->GetWidth() == 4)
     115             :     {
     116         825 :         if (strlen(pachData) < 5)
     117           0 :             return FALSE;
     118             : 
     119         825 :         memcpy(szModule, pachData, 4);
     120         825 :         szModule[4] = '\0';
     121             : 
     122         825 :         nRecord = atoi(pachData + 4);
     123             :     }
     124             :     else
     125             :     {
     126             :         DDFSubfieldDefn *poSF =
     127           2 :             poField->GetFieldDefn()->FindSubfieldDefn("MODN");
     128           2 :         if (poSF == nullptr)
     129           0 :             return FALSE;
     130             :         int nBytesRemaining;
     131           2 :         pachData = poField->GetSubfieldData(poSF, &nBytesRemaining);
     132           2 :         if (pachData == nullptr)
     133           0 :             return FALSE;
     134           2 :         snprintf(szModule, sizeof(szModule), "%s",
     135             :                  poSF->ExtractStringData(pachData, nBytesRemaining, nullptr));
     136             : 
     137           2 :         poSF = poField->GetFieldDefn()->FindSubfieldDefn("RCID");
     138           2 :         if (poSF != nullptr)
     139             :         {
     140           2 :             pachData = poField->GetSubfieldData(poSF, &nBytesRemaining);
     141           2 :             if (pachData != nullptr)
     142           2 :                 nRecord =
     143           2 :                     poSF->ExtractIntData(pachData, nBytesRemaining, nullptr);
     144             :         }
     145             :     }
     146             : 
     147         827 :     if (poDefn->GetSubfieldCount() == 3)
     148             :     {
     149             :         DDFSubfieldDefn *poSF =
     150         219 :             poField->GetFieldDefn()->FindSubfieldDefn("OBRP");
     151         219 :         if (poSF != nullptr)
     152             :         {
     153             :             int nBytesRemaining;
     154         219 :             pachData = poField->GetSubfieldData(poSF, &nBytesRemaining);
     155         219 :             if (pachData != nullptr)
     156             :             {
     157         219 :                 snprintf(szOBRP, sizeof(szOBRP), "%s",
     158             :                          poSF->ExtractStringData(pachData, nBytesRemaining,
     159             :                                                  nullptr));
     160             :             }
     161             :         }
     162             :     }
     163             : 
     164         827 :     return FALSE;
     165             : }
     166             : 
     167             : /************************************************************************/
     168             : /*                         SDTSModId::GetName()                         */
     169             : /************************************************************************/
     170             : 
     171           0 : const char *SDTSModId::GetName()
     172             : 
     173             : {
     174           0 :     snprintf(szName, sizeof(szName), "%s:%d", szModule, nRecord);
     175             : 
     176           0 :     return szName;
     177             : }
     178             : 
     179             : /************************************************************************/
     180             : /*                      SDTSScanModuleReferences()                      */
     181             : /*                                                                      */
     182             : /*      Find all modules references by records in this module based     */
     183             : /*      on a particular field name.  That field must be in module       */
     184             : /*      reference form (contain MODN/RCID subfields).                   */
     185             : /************************************************************************/
     186             : 
     187           5 : char **SDTSScanModuleReferences(DDFModule *poModule, const char *pszFName)
     188             : 
     189             : {
     190             :     /* -------------------------------------------------------------------- */
     191             :     /*      Identify the field, and subfield we are interested in.          */
     192             :     /* -------------------------------------------------------------------- */
     193           5 :     DDFFieldDefn *poIDField = poModule->FindFieldDefn(pszFName);
     194             : 
     195           5 :     if (poIDField == nullptr)
     196           2 :         return nullptr;
     197             : 
     198           3 :     DDFSubfieldDefn *poMODN = poIDField->FindSubfieldDefn("MODN");
     199           3 :     if (poMODN == nullptr)
     200           0 :         return nullptr;
     201             : 
     202             :     /* -------------------------------------------------------------------- */
     203             :     /*      Scan the file.                                                  */
     204             :     /* -------------------------------------------------------------------- */
     205           3 :     poModule->Rewind();
     206             : 
     207           3 :     DDFRecord *poRecord = nullptr;
     208           6 :     CPLStringList aosModnList;
     209           6 :     std::set<std::string> aoSetModNames;
     210         153 :     while ((poRecord = poModule->ReadRecord()) != nullptr)
     211             :     {
     212         679 :         for (int iField = 0; iField < poRecord->GetFieldCount(); iField++)
     213             :         {
     214         529 :             DDFField *poField = poRecord->GetField(iField);
     215             : 
     216         529 :             if (poField->GetFieldDefn() == poIDField)
     217             :             {
     218          12 :                 for (int i = 0; i < poField->GetRepeatCount(); i++)
     219             :                 {
     220             :                     const char *pszModName =
     221           6 :                         poField->GetSubfieldData(poMODN, nullptr, i);
     222             : 
     223           6 :                     if (pszModName == nullptr || strlen(pszModName) < 4)
     224           0 :                         continue;
     225             : 
     226             :                     char szName[5];
     227           6 :                     strncpy(szName, pszModName, 4);
     228           6 :                     szName[4] = '\0';
     229             : 
     230           6 :                     if (aoSetModNames.find(szName) == aoSetModNames.end())
     231             :                     {
     232           1 :                         aoSetModNames.insert(szName);
     233           1 :                         aosModnList.AddString(szName);
     234             :                     }
     235             :                 }
     236             :             }
     237             :         }
     238             :     }
     239             : 
     240           3 :     poModule->Rewind();
     241             : 
     242           3 :     return aosModnList.StealList();
     243             : }

Generated by: LCOV version 1.14