LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/ntf - ntfrecord.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 0 85 0.0 %
Date: 2024-05-04 12:52:34 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  NTF Translator
       4             :  * Purpose:  NTFRecord class implementation.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 1999, Frank Warmerdam
       9             :  * Copyright (c) 2013, Even Rouault <even dot rouault at spatialys.com>
      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 "ntf.h"
      31             : #include "cpl_conv.h"
      32             : 
      33             : static int nFieldBufSize = 0;
      34             : static char *pszFieldBuf = nullptr;
      35             : 
      36             : constexpr int MAX_RECORD_LEN = 160;
      37             : 
      38             : /************************************************************************/
      39             : /*                             NTFRecord()                              */
      40             : /*                                                                      */
      41             : /*      The constructor is where the record is read.  This includes     */
      42             : /*      transparent merging of continuation lines.                      */
      43             : /************************************************************************/
      44             : 
      45           0 : NTFRecord::NTFRecord(VSILFILE *fp) : nType(99), nLength(0), pszData(nullptr)
      46             : {
      47           0 :     if (fp == nullptr)
      48           0 :         return;
      49             : 
      50             :     /* ==================================================================== */
      51             :     /*      Read lines until we get to one without a continuation mark.     */
      52             :     /* ==================================================================== */
      53           0 :     char szLine[MAX_RECORD_LEN + 3] = {};
      54           0 :     int nNewLength = 0;
      55             : 
      56           0 :     do
      57             :     {
      58           0 :         nNewLength = ReadPhysicalLine(fp, szLine);
      59           0 :         if (nNewLength == -1 || nNewLength == -2)
      60             :             break;
      61             : 
      62           0 :         while (nNewLength > 0 && szLine[nNewLength - 1] == ' ')
      63           0 :             szLine[--nNewLength] = '\0';
      64             : 
      65           0 :         if (nNewLength < 2 || szLine[nNewLength - 1] != '%')
      66             :         {
      67           0 :             CPLError(CE_Failure, CPLE_AppDefined,
      68             :                      "Corrupt NTF record, missing end '%%'.");
      69           0 :             CPLFree(pszData);
      70           0 :             pszData = nullptr;
      71           0 :             break;
      72             :         }
      73             : 
      74           0 :         if (pszData == nullptr)
      75             :         {
      76           0 :             nLength = nNewLength - 2;
      77           0 :             pszData = static_cast<char *>(VSI_MALLOC_VERBOSE(nLength + 1));
      78           0 :             if (pszData == nullptr)
      79             :             {
      80           0 :                 return;
      81             :             }
      82           0 :             memcpy(pszData, szLine, nLength);
      83           0 :             pszData[nLength] = '\0';
      84             :         }
      85             :         else
      86             :         {
      87           0 :             if (!STARTS_WITH_CI(szLine, "00") || nNewLength < 4)
      88             :             {
      89           0 :                 CPLError(CE_Failure, CPLE_AppDefined, "Invalid line");
      90           0 :                 VSIFree(pszData);
      91           0 :                 pszData = nullptr;
      92           0 :                 return;
      93             :             }
      94             : 
      95             :             char *pszNewData = static_cast<char *>(
      96           0 :                 VSI_REALLOC_VERBOSE(pszData, nLength + (nNewLength - 4) + 1));
      97           0 :             if (pszNewData == nullptr)
      98             :             {
      99           0 :                 VSIFree(pszData);
     100           0 :                 pszData = nullptr;
     101           0 :                 return;
     102             :             }
     103             : 
     104           0 :             pszData = pszNewData;
     105           0 :             memcpy(pszData + nLength, szLine + 2, nNewLength - 4);
     106           0 :             nLength += nNewLength - 4;
     107           0 :             pszData[nLength] = '\0';
     108             :         }
     109           0 :     } while (szLine[nNewLength - 2] == '1');
     110             : 
     111             :     /* -------------------------------------------------------------------- */
     112             :     /*      Figure out the record type.                                     */
     113             :     /* -------------------------------------------------------------------- */
     114           0 :     if (pszData != nullptr)
     115             :     {
     116             :         char szType[3];
     117             : 
     118           0 :         strncpy(szType, pszData, 2);
     119           0 :         szType[2] = '\0';
     120             : 
     121           0 :         nType = atoi(szType);
     122             :     }
     123             : }
     124             : 
     125             : /************************************************************************/
     126             : /*                             ~NTFRecord()                             */
     127             : /************************************************************************/
     128             : 
     129           0 : NTFRecord::~NTFRecord()
     130             : 
     131             : {
     132           0 :     CPLFree(pszData);
     133             : 
     134           0 :     if (pszFieldBuf != nullptr)
     135             :     {
     136           0 :         CPLFree(pszFieldBuf);
     137           0 :         pszFieldBuf = nullptr;
     138           0 :         nFieldBufSize = 0;
     139             :     }
     140           0 : }
     141             : 
     142             : /************************************************************************/
     143             : /*                          ReadPhysicalLine()                          */
     144             : /************************************************************************/
     145             : 
     146           0 : int NTFRecord::ReadPhysicalLine(VSILFILE *fp, char *pszLine)
     147             : 
     148             : {
     149             :     /* -------------------------------------------------------------------- */
     150             :     /*      Read enough data that we are sure we have a whole record.       */
     151             :     /* -------------------------------------------------------------------- */
     152           0 :     int nRecordStart = static_cast<int>(VSIFTellL(fp));
     153             :     const int nBytesRead =
     154           0 :         static_cast<int>(VSIFReadL(pszLine, 1, MAX_RECORD_LEN + 2, fp));
     155             : 
     156           0 :     if (nBytesRead == 0)
     157             :     {
     158           0 :         if (VSIFEofL(fp))
     159           0 :             return -1;
     160             :         else
     161             :         {
     162           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     163             :                      "Low level read error occurred while reading NTF file.");
     164           0 :             return -2;
     165             :         }
     166             :     }
     167             : 
     168             :     /* -------------------------------------------------------------------- */
     169             :     /*      Search for CR or LF.                                            */
     170             :     /* -------------------------------------------------------------------- */
     171           0 :     int i = 0;  // Used after for.
     172           0 :     for (; i < nBytesRead; i++)
     173             :     {
     174           0 :         if (pszLine[i] == 10 || pszLine[i] == 13)
     175             :             break;
     176             :     }
     177             : 
     178             :     /* -------------------------------------------------------------------- */
     179             :     /*      If we don't find EOL within 80 characters something has gone    */
     180             :     /*      badly wrong!                                                    */
     181             :     /* -------------------------------------------------------------------- */
     182           0 :     if (i == MAX_RECORD_LEN + 2)
     183             :     {
     184           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     185             :                  "%d byte record too long for NTF format.  "
     186             :                  "No line may be longer than 80 characters though up "
     187             :                  "to %d tolerated.",
     188             :                  nBytesRead, MAX_RECORD_LEN);
     189           0 :         return -2;
     190             :     }
     191             : 
     192             :     /* -------------------------------------------------------------------- */
     193             :     /*      Trim CR/LF.                                                     */
     194             :     /* -------------------------------------------------------------------- */
     195           0 :     const int l_nLength = i;
     196           0 :     const int nRecordEnd =
     197           0 :         nRecordStart + i +
     198           0 :         (pszLine[i + 1] == 10 || pszLine[i + 1] == 13 ? 2 : 1);
     199             : 
     200           0 :     pszLine[l_nLength] = '\0';
     201             : 
     202             :     /* -------------------------------------------------------------------- */
     203             :     /*      Restore read pointer to beginning of next record.               */
     204             :     /* -------------------------------------------------------------------- */
     205           0 :     if (VSIFSeekL(fp, nRecordEnd, SEEK_SET) != 0)
     206           0 :         return -1;
     207             : 
     208           0 :     return l_nLength;
     209             : }
     210             : 
     211             : /************************************************************************/
     212             : /*                              GetField()                              */
     213             : /*                                                                      */
     214             : /*      Note that the start position is 1 based, to match the           */
     215             : /*      notation in the NTF document.  The returned pointer is to an    */
     216             : /*      internal buffer, but is zero terminated.                        */
     217             : /************************************************************************/
     218             : 
     219           0 : const char *NTFRecord::GetField(int nStart, int nEnd)
     220             : 
     221             : {
     222           0 :     const int nSize = nEnd - nStart + 1;
     223             : 
     224           0 :     if (pszData == nullptr)
     225           0 :         return "";
     226             : 
     227             :     /* -------------------------------------------------------------------- */
     228             :     /*      Reallocate working buffer larger if needed.                     */
     229             :     /* -------------------------------------------------------------------- */
     230           0 :     if (nFieldBufSize < nSize + 1)
     231             :     {
     232           0 :         CPLFree(pszFieldBuf);
     233           0 :         nFieldBufSize = nSize + 1;
     234           0 :         pszFieldBuf = static_cast<char *>(CPLMalloc(nFieldBufSize));
     235             :     }
     236             : 
     237             :     /* -------------------------------------------------------------------- */
     238             :     /*      Copy out desired data.                                          */
     239             :     /* -------------------------------------------------------------------- */
     240           0 :     if (nStart + nSize > nLength + 1)
     241             :     {
     242           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     243             :                  "Attempt to read %d to %d, beyond the end of %d byte long\n"
     244             :                  "type `%2.2s' record.\n",
     245             :                  nStart, nEnd, nLength, pszData);
     246           0 :         memset(pszFieldBuf, ' ', nSize);
     247           0 :         pszFieldBuf[nSize] = '\0';
     248             :     }
     249             :     else
     250             :     {
     251           0 :         strncpy(pszFieldBuf, pszData + nStart - 1, nSize);
     252           0 :         pszFieldBuf[nSize] = '\0';
     253             :     }
     254             : 
     255           0 :     return pszFieldBuf;
     256             : }

Generated by: LCOV version 1.14