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-11-21 22:18:42 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             :  * SPDX-License-Identifier: MIT
      13             :  ****************************************************************************/
      14             : 
      15             : #include "sdts_al.h"
      16             : #include "cpl_string.h"
      17             : 
      18             : #include <set>
      19             : 
      20             : /************************************************************************/
      21             : /*                            SDTSFeature()                             */
      22             : /************************************************************************/
      23             : 
      24         572 : SDTSFeature::SDTSFeature() : nAttributes(0), paoATID(nullptr)
      25             : {
      26         572 : }
      27             : 
      28             : /************************************************************************/
      29             : /*                       SDTSFeature::ApplyATID()                       */
      30             : /************************************************************************/
      31             : 
      32          12 : void SDTSFeature::ApplyATID(DDFField *poField)
      33             : 
      34             : {
      35          12 :     DDFSubfieldDefn *poMODN = poField->GetFieldDefn()->FindSubfieldDefn("MODN");
      36          12 :     if (poMODN == nullptr)
      37             :     {
      38             :         // CPLAssert( false );
      39           0 :         return;
      40             :     }
      41             : 
      42          12 :     bool bUsualFormat = poMODN->GetWidth() == 4;
      43          12 :     const int nRepeatCount = poField->GetRepeatCount();
      44          24 :     for (int iRepeat = 0; iRepeat < nRepeatCount; iRepeat++)
      45             :     {
      46          12 :         paoATID = reinterpret_cast<SDTSModId *>(
      47          12 :             CPLRealloc(paoATID, sizeof(SDTSModId) * (nAttributes + 1)));
      48             : 
      49          12 :         SDTSModId *poModId = paoATID + nAttributes;
      50          12 :         *poModId = SDTSModId();
      51             : 
      52          12 :         if (bUsualFormat)
      53             :         {
      54             :             const char *pabyData =
      55          12 :                 poField->GetSubfieldData(poMODN, nullptr, iRepeat);
      56          12 :             if (pabyData == nullptr || strlen(pabyData) < 5)
      57           0 :                 return;
      58             : 
      59          12 :             memcpy(poModId->szModule, pabyData, 4);
      60          12 :             poModId->szModule[4] = '\0';
      61          12 :             poModId->nRecord = atoi(pabyData + 4);
      62          12 :             poModId->szOBRP[0] = '\0';
      63             :         }
      64             :         else
      65             :         {
      66           0 :             poModId->Set(poField);
      67             :         }
      68             : 
      69          12 :         nAttributes++;
      70             :     }
      71             : }
      72             : 
      73             : /************************************************************************/
      74             : /*                            ~SDTSFeature()                            */
      75             : /************************************************************************/
      76             : 
      77        1144 : SDTSFeature::~SDTSFeature()
      78             : 
      79             : {
      80         572 :     CPLFree(paoATID);
      81         572 :     paoATID = nullptr;
      82         572 : }
      83             : 
      84             : /************************************************************************/
      85             : /*                           SDTSModId::Set()                           */
      86             : /*                                                                      */
      87             : /*      Set a module from a field.  We depend on our pre-knowledge      */
      88             : /*      of the data layout to fetch more efficiently.                   */
      89             : /************************************************************************/
      90             : 
      91         827 : int SDTSModId::Set(DDFField *poField)
      92             : 
      93             : {
      94         827 :     const char *pachData = poField->GetData();
      95         827 :     DDFFieldDefn *poDefn = poField->GetFieldDefn();
      96             : 
      97        1654 :     if (poDefn->GetSubfieldCount() >= 2 &&
      98         827 :         poDefn->GetSubfield(0)->GetWidth() == 4)
      99             :     {
     100         825 :         if (strlen(pachData) < 5)
     101           0 :             return FALSE;
     102             : 
     103         825 :         memcpy(szModule, pachData, 4);
     104         825 :         szModule[4] = '\0';
     105             : 
     106         825 :         nRecord = atoi(pachData + 4);
     107             :     }
     108             :     else
     109             :     {
     110             :         DDFSubfieldDefn *poSF =
     111           2 :             poField->GetFieldDefn()->FindSubfieldDefn("MODN");
     112           2 :         if (poSF == nullptr)
     113           0 :             return FALSE;
     114             :         int nBytesRemaining;
     115           2 :         pachData = poField->GetSubfieldData(poSF, &nBytesRemaining);
     116           2 :         if (pachData == nullptr)
     117           0 :             return FALSE;
     118           2 :         snprintf(szModule, sizeof(szModule), "%s",
     119             :                  poSF->ExtractStringData(pachData, nBytesRemaining, nullptr));
     120             : 
     121           2 :         poSF = poField->GetFieldDefn()->FindSubfieldDefn("RCID");
     122           2 :         if (poSF != nullptr)
     123             :         {
     124           2 :             pachData = poField->GetSubfieldData(poSF, &nBytesRemaining);
     125           2 :             if (pachData != nullptr)
     126           2 :                 nRecord =
     127           2 :                     poSF->ExtractIntData(pachData, nBytesRemaining, nullptr);
     128             :         }
     129             :     }
     130             : 
     131         827 :     if (poDefn->GetSubfieldCount() == 3)
     132             :     {
     133             :         DDFSubfieldDefn *poSF =
     134         219 :             poField->GetFieldDefn()->FindSubfieldDefn("OBRP");
     135         219 :         if (poSF != nullptr)
     136             :         {
     137             :             int nBytesRemaining;
     138         219 :             pachData = poField->GetSubfieldData(poSF, &nBytesRemaining);
     139         219 :             if (pachData != nullptr)
     140             :             {
     141         219 :                 snprintf(szOBRP, sizeof(szOBRP), "%s",
     142             :                          poSF->ExtractStringData(pachData, nBytesRemaining,
     143             :                                                  nullptr));
     144             :             }
     145             :         }
     146             :     }
     147             : 
     148         827 :     return FALSE;
     149             : }
     150             : 
     151             : /************************************************************************/
     152             : /*                         SDTSModId::GetName()                         */
     153             : /************************************************************************/
     154             : 
     155           0 : const char *SDTSModId::GetName()
     156             : 
     157             : {
     158           0 :     snprintf(szName, sizeof(szName), "%s:%d", szModule, nRecord);
     159             : 
     160           0 :     return szName;
     161             : }
     162             : 
     163             : /************************************************************************/
     164             : /*                      SDTSScanModuleReferences()                      */
     165             : /*                                                                      */
     166             : /*      Find all modules references by records in this module based     */
     167             : /*      on a particular field name.  That field must be in module       */
     168             : /*      reference form (contain MODN/RCID subfields).                   */
     169             : /************************************************************************/
     170             : 
     171           5 : char **SDTSScanModuleReferences(DDFModule *poModule, const char *pszFName)
     172             : 
     173             : {
     174             :     /* -------------------------------------------------------------------- */
     175             :     /*      Identify the field, and subfield we are interested in.          */
     176             :     /* -------------------------------------------------------------------- */
     177           5 :     DDFFieldDefn *poIDField = poModule->FindFieldDefn(pszFName);
     178             : 
     179           5 :     if (poIDField == nullptr)
     180           2 :         return nullptr;
     181             : 
     182           3 :     DDFSubfieldDefn *poMODN = poIDField->FindSubfieldDefn("MODN");
     183           3 :     if (poMODN == nullptr)
     184           0 :         return nullptr;
     185             : 
     186             :     /* -------------------------------------------------------------------- */
     187             :     /*      Scan the file.                                                  */
     188             :     /* -------------------------------------------------------------------- */
     189           3 :     poModule->Rewind();
     190             : 
     191           3 :     DDFRecord *poRecord = nullptr;
     192           6 :     CPLStringList aosModnList;
     193           6 :     std::set<std::string> aoSetModNames;
     194         153 :     while ((poRecord = poModule->ReadRecord()) != nullptr)
     195             :     {
     196         679 :         for (int iField = 0; iField < poRecord->GetFieldCount(); iField++)
     197             :         {
     198         529 :             DDFField *poField = poRecord->GetField(iField);
     199             : 
     200         529 :             if (poField->GetFieldDefn() == poIDField)
     201             :             {
     202          12 :                 for (int i = 0; i < poField->GetRepeatCount(); i++)
     203             :                 {
     204             :                     const char *pszModName =
     205           6 :                         poField->GetSubfieldData(poMODN, nullptr, i);
     206             : 
     207           6 :                     if (pszModName == nullptr || strlen(pszModName) < 4)
     208           0 :                         continue;
     209             : 
     210             :                     char szName[5];
     211           6 :                     strncpy(szName, pszModName, 4);
     212           6 :                     szName[4] = '\0';
     213             : 
     214           6 :                     if (aoSetModNames.find(szName) == aoSetModNames.end())
     215             :                     {
     216           1 :                         aoSetModNames.insert(szName);
     217           1 :                         aosModnList.AddString(szName);
     218             :                     }
     219             :                 }
     220             :             }
     221             :         }
     222             :     }
     223             : 
     224           3 :     poModule->Rewind();
     225             : 
     226           3 :     return aosModnList.StealList();
     227             : }

Generated by: LCOV version 1.14