LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/mitab - mitab_middatafile.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 109 121 90.1 %
Date: 2024-11-21 22:18:42 Functions: 19 19 100.0 %

          Line data    Source code
       1             : /**********************************************************************
       2             :  *
       3             :  * Name:     mitab_datfile.cpp
       4             :  * Project:  MapInfo TAB Read/Write library
       5             :  * Language: C++
       6             :  * Purpose:  Implementation of the MIDDATAFile class used to handle
       7             :  *           reading/writing of the MID/MIF files
       8             :  * Author:   Stephane Villeneuve, stephane.v@videotron.ca
       9             :  *
      10             :  **********************************************************************
      11             :  * Copyright (c) 1999, 2000, Stephane Villeneuve
      12             :  *
      13             :  * SPDX-License-Identifier: MIT
      14             :  **********************************************************************/
      15             : 
      16             : #include "cpl_port.h"
      17             : #include "mitab.h"
      18             : 
      19             : #include <cstdarg>
      20             : #include <cstddef>
      21             : 
      22             : #include "cpl_conv.h"
      23             : #include "cpl_csv.h"
      24             : #include "cpl_error.h"
      25             : #include "cpl_string.h"
      26             : #include "cpl_vsi.h"
      27             : #include "mitab_priv.h"
      28             : 
      29             : /*=====================================================================
      30             :  *                      class MIDDATAFile
      31             :  *
      32             :  *====================================================================*/
      33             : 
      34        1146 : MIDDATAFile::MIDDATAFile(const char *pszEncoding)
      35             :     : m_fp(nullptr), m_pszDelimiter("\t"),  // Encom 2003 (was NULL).
      36             :       m_pszFname(nullptr), m_eAccessMode(TABRead), m_dfXMultiplier(1.0),
      37             :       m_dfYMultiplier(1.0), m_dfXDisplacement(0.0), m_dfYDisplacement(0.0),
      38        1146 :       m_bEof(FALSE), m_osEncoding(pszEncoding)
      39             : {
      40        1146 : }
      41             : 
      42        1146 : MIDDATAFile::~MIDDATAFile()
      43             : {
      44        1146 :     Close();
      45        1146 : }
      46             : 
      47        2084 : void MIDDATAFile::SaveLine(const char *pszLine)
      48             : {
      49        2084 :     if (pszLine == nullptr)
      50             :     {
      51           0 :         m_osSavedLine.clear();
      52             :     }
      53             :     else
      54             :     {
      55        2084 :         m_osSavedLine = pszLine;
      56             :     }
      57        2084 : }
      58             : 
      59        2065 : const char *MIDDATAFile::GetSavedLine()
      60             : {
      61        2065 :     return m_osSavedLine.c_str();
      62             : }
      63             : 
      64        1146 : int MIDDATAFile::Open(const char *pszFname, const char *pszAccess)
      65             : {
      66        1146 :     if (m_fp)
      67             :     {
      68           0 :         return -1;
      69             :     }
      70             : 
      71             :     // Validate access mode and make sure we use Text access.
      72        1146 :     if (STARTS_WITH_CI(pszAccess, "r"))
      73             :     {
      74         972 :         m_eAccessMode = TABRead;
      75         972 :         pszAccess = "rt";
      76             :     }
      77         174 :     else if (STARTS_WITH_CI(pszAccess, "w"))
      78             :     {
      79         174 :         m_eAccessMode = TABWrite;
      80         174 :         pszAccess = "wt";
      81             :     }
      82             :     else
      83             :     {
      84           0 :         return -1;
      85             :     }
      86             : 
      87             :     // Open file for reading.
      88        1146 :     m_pszFname = CPLStrdup(pszFname);
      89        1146 :     m_fp = VSIFOpenL(m_pszFname, pszAccess);
      90             : 
      91        1146 :     if (m_fp == nullptr)
      92             :     {
      93           4 :         CPLFree(m_pszFname);
      94           4 :         m_pszFname = nullptr;
      95           4 :         return -1;
      96             :     }
      97             : 
      98        1142 :     SetEof(FALSE);
      99        1142 :     return 0;
     100             : }
     101             : 
     102         983 : int MIDDATAFile::Rewind()
     103             : {
     104         983 :     if (m_fp == nullptr || m_eAccessMode == TABWrite)
     105           0 :         return -1;
     106             : 
     107             :     else
     108             :     {
     109         983 :         VSIRewindL(m_fp);
     110         983 :         SetEof(FALSE);
     111             :     }
     112         983 :     return 0;
     113             : }
     114             : 
     115        2288 : int MIDDATAFile::Close()
     116             : {
     117        2288 :     if (m_fp == nullptr)
     118        1146 :         return 0;
     119             : 
     120             :     // Close file
     121        1142 :     VSIFCloseL(m_fp);
     122        1142 :     m_fp = nullptr;
     123             : 
     124             :     // clear readline buffer.
     125        1142 :     CPLReadLineL(nullptr);
     126             : 
     127        1142 :     CPLFree(m_pszFname);
     128        1142 :     m_pszFname = nullptr;
     129             : 
     130        1142 :     return 0;
     131             : }
     132             : 
     133       50142 : const char *MIDDATAFile::GetLine()
     134             : {
     135       50142 :     if (m_eAccessMode != TABRead)
     136             :     {
     137           0 :         CPLAssert(false);
     138             :         return nullptr;
     139             :     }
     140             : 
     141             :     static const int nMaxLineLength =
     142       50142 :         atoi(CPLGetConfigOption("MITAB_MAX_LINE_LENGTH", "1000000"));
     143       50142 :     const char *pszLine = CPLReadLine2L(m_fp, nMaxLineLength, nullptr);
     144             : 
     145       50142 :     if (pszLine == nullptr)
     146             :     {
     147         615 :         if (strstr(CPLGetLastErrorMsg(),
     148         615 :                    "Maximum number of characters allowed reached"))
     149             :         {
     150           0 :             CPLError(
     151             :                 CE_Failure, CPLE_AppDefined,
     152             :                 "Maximum number of characters allowed reached. "
     153             :                 "You can set the MITAB_MAX_LINE_LENGTH configuration option "
     154             :                 "to the desired number of bytes (or -1 for unlimited)");
     155             :         }
     156         615 :         SetEof(TRUE);
     157         615 :         m_osLastRead.clear();
     158             :     }
     159             :     else
     160             :     {
     161             :         // Skip leading spaces and tabs except if the delimiter is tab.
     162       84284 :         while (*pszLine == ' ' || (*m_pszDelimiter != '\t' && *pszLine == '\t'))
     163       34757 :             pszLine++;
     164             : 
     165       49527 :         m_osLastRead = pszLine;
     166             :     }
     167             : 
     168             : #if DEBUG_VERBOSE
     169             :     if (pszLine)
     170             :         CPLDebug("MITAB", "pszLine: %s", pszLine);
     171             : #endif
     172             : 
     173       50142 :     return pszLine;
     174             : }
     175             : 
     176       32042 : const char *MIDDATAFile::GetLastLine()
     177             : {
     178             :     // Return NULL if EOF.
     179       32042 :     if (GetEof())
     180             :     {
     181         895 :         return nullptr;
     182             :     }
     183       31147 :     if (m_eAccessMode == TABRead)
     184             :     {
     185             : #if DEBUG_VERBOSE
     186             :         CPLDebug("MITAB", "m_osLastRead: %s", m_osLastRead.c_str());
     187             : #endif
     188       31147 :         return m_osLastRead.c_str();
     189             :     }
     190             : 
     191             :     // We should never get here.  Read/Write mode not implemented.
     192           0 :     CPLAssert(false);
     193             :     return nullptr;
     194             : }
     195             : 
     196         367 : char **MIDDATAFile::GetTokenizedNextLine()
     197             : {
     198             :     static const int nMaxLineLength =
     199         367 :         atoi(CPLGetConfigOption("MITAB_MAX_LINE_LENGTH", "1000000"));
     200             :     char **papszTokens =
     201         367 :         CSVReadParseLine3L(m_fp, nMaxLineLength, m_pszDelimiter,
     202             :                            true,   // bHonourStrings
     203             :                            false,  // bKeepLeadingAndClosingQuotes
     204             :                            false,  // bMergeDelimiter
     205             :                            false   // bSkipBOM
     206             :         );
     207         367 :     if (papszTokens == nullptr)
     208             :     {
     209           0 :         if (strstr(CPLGetLastErrorMsg(),
     210           0 :                    "Maximum number of characters allowed reached"))
     211             :         {
     212           0 :             CPLError(
     213             :                 CE_Failure, CPLE_AppDefined,
     214             :                 "Maximum number of characters allowed reached. "
     215             :                 "You can set the MITAB_MAX_LINE_LENGTH configuration option "
     216             :                 "to the desired number of bytes (or -1 for unlimited)");
     217             :         }
     218           0 :         SetEof(TRUE);
     219             :     }
     220         367 :     return papszTokens;
     221             : }
     222             : 
     223        1752 : void MIDDATAFile::WriteLine(const char *pszFormat, ...)
     224             : {
     225             :     va_list args;
     226             : 
     227        1752 :     if (m_eAccessMode == TABWrite && m_fp)
     228             :     {
     229        1752 :         va_start(args, pszFormat);
     230        1752 :         CPLString osStr;
     231        1752 :         osStr.vPrintf(pszFormat, args);
     232        1752 :         VSIFWriteL(osStr.c_str(), 1, osStr.size(), m_fp);
     233        1752 :         va_end(args);
     234             :     }
     235             :     else
     236             :     {
     237           0 :         CPLAssert(false);
     238             :     }
     239        1752 : }
     240             : 
     241        1084 : void MIDDATAFile::SetTranslation(double dfXMul, double dfYMul, double dfXTran,
     242             :                                  double dfYTran)
     243             : {
     244        1084 :     m_dfXMultiplier = dfXMul;
     245        1084 :     m_dfYMultiplier = dfYMul;
     246        1084 :     m_dfXDisplacement = dfXTran;
     247        1084 :     m_dfYDisplacement = dfYTran;
     248        1084 : }
     249             : 
     250       21467 : double MIDDATAFile::GetXTrans(double dfX)
     251             : {
     252       21467 :     return (dfX * m_dfXMultiplier) + m_dfXDisplacement;
     253             : }
     254             : 
     255       20835 : double MIDDATAFile::GetYTrans(double dfY)
     256             : {
     257       20835 :     return (dfY * m_dfYMultiplier) + m_dfYDisplacement;
     258             : }
     259             : 
     260       23049 : GBool MIDDATAFile::IsValidFeature(const char *pszString)
     261             : {
     262       23049 :     char **papszToken = CSLTokenizeString(pszString);
     263             : 
     264       23049 :     if (CSLCount(papszToken) == 0)
     265             :     {
     266        8240 :         CSLDestroy(papszToken);
     267        8240 :         return FALSE;
     268             :     }
     269             : 
     270       14809 :     if (EQUAL(papszToken[0], "NONE") || EQUAL(papszToken[0], "POINT") ||
     271       11898 :         EQUAL(papszToken[0], "LINE") || EQUAL(papszToken[0], "PLINE") ||
     272        9461 :         EQUAL(papszToken[0], "REGION") || EQUAL(papszToken[0], "ARC") ||
     273        8234 :         EQUAL(papszToken[0], "TEXT") || EQUAL(papszToken[0], "RECT") ||
     274        7441 :         EQUAL(papszToken[0], "ROUNDRECT") || EQUAL(papszToken[0], "ELLIPSE") ||
     275        6598 :         EQUAL(papszToken[0], "MULTIPOINT") ||
     276        6415 :         EQUAL(papszToken[0], "COLLECTION"))
     277             :     {
     278        8493 :         CSLDestroy(papszToken);
     279        8493 :         return TRUE;
     280             :     }
     281             : 
     282        6316 :     CSLDestroy(papszToken);
     283        6316 :     return FALSE;
     284             : }
     285             : 
     286       32042 : GBool MIDDATAFile::GetEof()
     287             : {
     288       32042 :     return m_bEof;
     289             : }
     290             : 
     291         895 : const CPLString &MIDDATAFile::GetEncoding() const
     292             : {
     293         895 :     return m_osEncoding;
     294             : }
     295             : 
     296        1213 : void MIDDATAFile::SetEncoding(const CPLString &osEncoding)
     297             : {
     298        1213 :     m_osEncoding = osEncoding;
     299        1213 : }
     300             : 
     301        2740 : void MIDDATAFile::SetEof(GBool bEof)
     302             : {
     303        2740 :     m_bEof = bEof;
     304        2740 : }

Generated by: LCOV version 1.14