LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/mitab - mitab.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 103 195 52.8 %
Date: 2025-09-10 17:48:50 Functions: 47 92 51.1 %

          Line data    Source code
       1             : /**********************************************************************
       2             :  *
       3             :  * Name:     mitab.h
       4             :  * Project:  MapInfo TAB Read/Write library
       5             :  * Language: C++
       6             :  * Purpose:  Header file containing public definitions for the library.
       7             :  * Author:   Daniel Morissette, dmorissette@dmsolutions.ca
       8             :  *
       9             :  **********************************************************************
      10             :  * Copyright (c) 1999-2005, Daniel Morissette
      11             :  * Copyright (c) 2014, Even Rouault <even.rouault at spatialys.com>
      12             :  *
      13             :  * SPDX-License-Identifier: MIT
      14             :  **********************************************************************/
      15             : 
      16             : #ifndef MITAB_H_INCLUDED_
      17             : #define MITAB_H_INCLUDED_
      18             : 
      19             : #include "mitab_priv.h"
      20             : #include "ogr_feature.h"
      21             : #include "ogr_featurestyle.h"
      22             : #include "ogrsf_frmts.h"
      23             : 
      24             : #include <set>
      25             : 
      26             : /*---------------------------------------------------------------------
      27             :  * Current version of the MITAB library... always useful!
      28             :  *--------------------------------------------------------------------*/
      29             : #define MITAB_VERSION "2.0.0-dev (2008-10)"
      30             : #define MITAB_VERSION_INT 2000000 /* version x.y.z -> xxxyyyzzz */
      31             : 
      32             : #ifndef ROUND_INT
      33             : #define ROUND_INT(dX) static_cast<int>((dX) < 0.0 ? (dX)-0.5 : (dX) + 0.5)
      34             : #endif
      35             : 
      36             : #define MITAB_AREA(x1, y1, x2, y2)                                             \
      37             :     ((static_cast<double>(x2) - (x1)) * (static_cast<double>(y2) - (y1)))
      38             : 
      39             : class TABFeature;
      40             : 
      41             : /*---------------------------------------------------------------------
      42             :  * Codes for the GetFileClass() in the IMapInfoFile-derived  classes
      43             :  *--------------------------------------------------------------------*/
      44             : typedef enum
      45             : {
      46             :     TABFC_IMapInfoFile = 0,
      47             :     TABFC_TABFile,
      48             :     TABFC_TABView,
      49             :     TABFC_TABSeamless,
      50             :     TABFC_MIFFile
      51             : } TABFileClass;
      52             : 
      53             : /*---------------------------------------------------------------------
      54             :  *                      class IMapInfoFile
      55             :  *
      56             :  * Virtual base class for the TABFile and MIFFile classes.
      57             :  *
      58             :  * This is the definition of the public interface methods that should
      59             :  * be available for any type of MapInfo dataset.
      60             :  *--------------------------------------------------------------------*/
      61             : 
      62             : class IMapInfoFile CPL_NON_FINAL : public OGRLayer
      63             : {
      64             :     CPL_DISALLOW_COPY_ASSIGN(IMapInfoFile)
      65             : 
      66             :   protected:
      67             :     GDALDataset *m_poDS = nullptr;
      68             :     GIntBig m_nCurFeatureId;
      69             :     TABFeature *m_poCurFeature;
      70             :     GBool m_bBoundsSet;
      71             : 
      72             :     char *m_pszCharset;
      73             :     bool m_bStrictLaundering = true;
      74             :     std::set<CPLString> m_oSetFields{};
      75             :     TABFeature *CreateTABFeature(OGRFeature *poFeature);
      76             : 
      77             :   public:
      78             :     IMapInfoFile(GDALDataset *poDS);
      79             :     ~IMapInfoFile() override;
      80             : 
      81           0 :     virtual TABFileClass GetFileClass()
      82             :     {
      83           0 :         return TABFC_IMapInfoFile;
      84             :     }
      85             : 
      86             :     virtual int Open(const char *pszFname, const char *pszAccess,
      87             :                      GBool bTestOpenNoError = FALSE,
      88             :                      const char *pszCharset = nullptr);
      89             : 
      90             :     virtual int Open(const char *pszFname, TABAccess eAccess,
      91             :                      GBool bTestOpenNoError = FALSE,
      92             :                      const char *pszCharset = nullptr) = 0;
      93             :     virtual int Close() = 0;
      94             : 
      95             :     virtual int
      96           0 :     SetQuickSpatialIndexMode(CPL_UNUSED GBool bQuickSpatialIndexMode = TRUE)
      97             :     {
      98           0 :         return -1;
      99             :     }
     100             : 
     101             :     virtual const char *GetTableName() = 0;
     102             : 
     103             :     ///////////////
     104             :     // Static method to detect file type, create an object to read that
     105             :     // file and open it.
     106             :     static IMapInfoFile *SmartOpen(GDALDataset *poDS, const char *pszFname,
     107             :                                    GBool bUpdate = FALSE,
     108             :                                    GBool bTestOpenNoError = FALSE);
     109             : 
     110             :     ///////////////
     111             :     //  OGR methods for read support
     112             :     void ResetReading() override = 0;
     113             :     GIntBig GetFeatureCount(int bForce) override = 0;
     114             :     OGRFeature *GetNextFeature() override;
     115             :     OGRFeature *GetFeature(GIntBig nFeatureId) override;
     116             :     OGRErr ICreateFeature(OGRFeature *poFeature) override;
     117             :     int TestCapability(const char *pszCap) const override = 0;
     118             :     OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
     119             :                       bool bForce) override = 0;
     120             : 
     121          23 :     GDALDataset *GetDataset() override
     122             :     {
     123          23 :         return m_poDS;
     124             :     }
     125             : 
     126             :     ///////////////
     127             :     // Read access specific stuff
     128             :     //
     129             :     virtual GIntBig GetNextFeatureId(GIntBig nPrevId) = 0;
     130             :     virtual TABFeature *GetFeatureRef(GIntBig nFeatureId) = 0;
     131             :     const OGRFeatureDefn *GetLayerDefn() const override = 0;
     132             : 
     133             :     virtual TABFieldType GetNativeFieldType(int nFieldId) = 0;
     134             : 
     135             :     virtual int GetBounds(double &dXMin, double &dYMin, double &dXMax,
     136             :                           double &dYMax, GBool bForce = TRUE) = 0;
     137             : 
     138             :     const OGRSpatialReference *GetSpatialRef() const override = 0;
     139             : 
     140             :     virtual int GetFeatureCountByType(int &numPoints, int &numLines,
     141             :                                       int &numRegions, int &numTexts,
     142             :                                       GBool bForce = TRUE) = 0;
     143             : 
     144             :     virtual GBool IsFieldIndexed(int nFieldId) = 0;
     145             :     virtual GBool IsFieldUnique(int nFieldId) = 0;
     146             : 
     147             :     ///////////////
     148             :     // Write access specific stuff
     149             :     //
     150         209 :     GBool IsBoundsSet()
     151             :     {
     152         209 :         return m_bBoundsSet;
     153             :     }
     154             : 
     155             :     virtual int SetBounds(double dXMin, double dYMin, double dXMax,
     156             :                           double dYMax) = 0;
     157             :     virtual int
     158             :     SetFeatureDefn(OGRFeatureDefn *poFeatureDefn,
     159             :                    TABFieldType *paeMapInfoNativeFieldTypes = nullptr) = 0;
     160             :     virtual int AddFieldNative(const char *pszName, TABFieldType eMapInfoType,
     161             :                                int nWidth = 0, int nPrecision = 0,
     162             :                                GBool bIndexed = FALSE, GBool bUnique = FALSE,
     163             :                                int bApproxOK = TRUE) = 0;
     164             :     virtual OGRErr CreateField(const OGRFieldDefn *poField,
     165             :                                int bApproxOK = TRUE) override;
     166             : 
     167             :     virtual int SetSpatialRef(OGRSpatialReference *poSpatialRef) = 0;
     168             : 
     169             :     virtual OGRErr CreateFeature(TABFeature *poFeature) = 0;
     170             : 
     171             :     virtual int SetFieldIndexed(int nFieldId) = 0;
     172             : 
     173             :     virtual int SetCharset(const char *charset);
     174             : 
     175             :     virtual const char *GetCharset() const;
     176             : 
     177             :     static const char *CharsetToEncoding(const char *);
     178             :     static const char *EncodingToCharset(const char *);
     179             : 
     180             :     void SetEncoding(const char *);
     181             :     const char *GetEncoding() const;
     182             :     virtual void SetStrictLaundering(bool);
     183             :     int TestUtf8Capability() const;
     184             :     CPLString NormalizeFieldName(const char *pszName) const;
     185             :     ///////////////
     186             :     // semi-private.
     187             :     virtual int GetProjInfo(TABProjInfo *poPI) = 0;
     188             :     virtual int SetProjInfo(TABProjInfo *poPI) = 0;
     189             :     virtual int SetMIFCoordSys(const char *pszMIFCoordSys) = 0;
     190             : 
     191             :     static int GetTABType(const OGRFieldDefn *poField, TABFieldType *peTABType,
     192             :                           int *pnWidth, int *pnPrecision);
     193             : 
     194             : #ifdef DEBUG
     195             :     virtual void Dump(FILE *fpOut = nullptr) = 0;
     196             : #endif
     197             : };
     198             : 
     199             : /*---------------------------------------------------------------------
     200             :  *                      class TABFile
     201             :  *
     202             :  * The main class for TAB datasets.  External programs should use this
     203             :  * class to open a TAB dataset and read/write features from/to it.
     204             :  *
     205             :  *--------------------------------------------------------------------*/
     206             : class TABFile final : public IMapInfoFile
     207             : {
     208             :     CPL_DISALLOW_COPY_ASSIGN(TABFile)
     209             : 
     210             :   private:
     211             :     char *m_pszFname;
     212             :     TABAccess m_eAccessMode;
     213             :     char **m_papszTABFile;
     214             :     int m_nVersion;
     215             :     int *m_panIndexNo;
     216             :     TABTableType m_eTableType;  // NATIVE (.DAT) or DBF
     217             : 
     218             :     TABDATFile *m_poDATFile;  // Attributes file
     219             :     TABMAPFile *m_poMAPFile;  // Object Geometry file
     220             :     TABINDFile *m_poINDFile;  // Attributes index file
     221             : 
     222             :     OGRFeatureDefn *m_poDefn;
     223             :     mutable OGRSpatialReference *m_poSpatialRef;
     224             :     int bUseSpatialTraversal;
     225             : 
     226             :     int m_nLastFeatureId;
     227             : 
     228             :     GIntBig *m_panMatchingFIDs;
     229             :     int m_iMatchingFID;
     230             : 
     231             :     int m_bNeedTABRewrite;
     232             : 
     233             :     int m_bLastOpWasRead;
     234             :     int m_bLastOpWasWrite;
     235             :     ///////////////
     236             :     // Private Read access specific stuff
     237             :     //
     238             :     int ParseTABFileFirstPass(GBool bTestOpenNoError);
     239             :     int ParseTABFileFields();
     240             : 
     241             :     ///////////////
     242             :     // Private Write access specific stuff
     243             :     //
     244             :     int WriteTABFile();
     245             : 
     246             :   public:
     247             :     explicit TABFile(GDALDataset *poDS);
     248             :     ~TABFile() override;
     249             : 
     250          67 :     TABFileClass GetFileClass() override
     251             :     {
     252          67 :         return TABFC_TABFile;
     253             :     }
     254             : 
     255           0 :     virtual int Open(const char *pszFname, const char *pszAccess,
     256             :                      GBool bTestOpenNoError = FALSE,
     257             :                      const char *pszCharset = nullptr) override
     258             :     {
     259           0 :         return IMapInfoFile::Open(pszFname, pszAccess, bTestOpenNoError,
     260           0 :                                   pszCharset);
     261             :     }
     262             : 
     263        1310 :     virtual int Open(const char *pszFname, TABAccess eAccess,
     264             :                      GBool bTestOpenNoError = FALSE,
     265             :                      const char *pszCharset = nullptr) override
     266             :     {
     267        1310 :         return Open(pszFname, eAccess, bTestOpenNoError, 512, pszCharset);
     268             :     }
     269             : 
     270             :     int Open(const char *pszFname, TABAccess eAccess, GBool bTestOpenNoError,
     271             :              int nBlockSizeForCreate, const char *pszCharset);
     272             : 
     273             :     int Close() override;
     274             : 
     275             :     virtual int
     276             :     SetQuickSpatialIndexMode(GBool bQuickSpatialIndexMode = TRUE) override;
     277             : 
     278           0 :     const char *GetTableName() override
     279             :     {
     280           0 :         return m_poDefn ? m_poDefn->GetName() : "";
     281             :     }
     282             : 
     283             :     void ResetReading() override;
     284             :     int TestCapability(const char *pszCap) const override;
     285             :     GIntBig GetFeatureCount(int bForce) override;
     286             :     OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
     287             :                       bool bForce) override;
     288             : 
     289             :     /* Implement OGRLayer's SetFeature() for random write, only with TABFile */
     290             :     OGRErr ISetFeature(OGRFeature *) override;
     291             :     OGRErr DeleteFeature(GIntBig nFeatureId) override;
     292             : 
     293             :     OGRErr DeleteField(int iField) override;
     294             :     OGRErr ReorderFields(int *panMap) override;
     295             :     virtual OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
     296             :                                   int nFlags) override;
     297             : 
     298             :     OGRErr SyncToDisk() override;
     299             : 
     300             :     CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
     301             :                            const char *pszDomain = "") override;
     302             : 
     303             :     ///////////////
     304             :     // Read access specific stuff
     305             :     //
     306             : 
     307             :     int GetNextFeatureId_Spatial(int nPrevId);
     308             : 
     309             :     GIntBig GetNextFeatureId(GIntBig nPrevId) override;
     310             :     TABFeature *GetFeatureRef(GIntBig nFeatureId) override;
     311             :     const OGRFeatureDefn *GetLayerDefn() const override;
     312             : 
     313             :     TABFieldType GetNativeFieldType(int nFieldId) override;
     314             : 
     315             :     virtual int GetBounds(double &dXMin, double &dYMin, double &dXMax,
     316             :                           double &dYMax, GBool bForce = TRUE) override;
     317             : 
     318             :     const OGRSpatialReference *GetSpatialRef() const override;
     319             : 
     320             :     virtual int GetFeatureCountByType(int &numPoints, int &numLines,
     321             :                                       int &numRegions, int &numTexts,
     322             :                                       GBool bForce = TRUE) override;
     323             : 
     324             :     GBool IsFieldIndexed(int nFieldId) override;
     325             : 
     326           0 :     GBool IsFieldUnique(int /*nFieldId*/) override
     327             :     {
     328           0 :         return FALSE;
     329             :     }
     330             : 
     331             :     int GetVersion()
     332             :     {
     333             :         return m_nVersion;
     334             :     }
     335             : 
     336             :     ///////////////
     337             :     // Write access specific stuff
     338             :     //
     339             :     virtual int SetBounds(double dXMin, double dYMin, double dXMax,
     340             :                           double dYMax) override;
     341             :     virtual int
     342             :     SetFeatureDefn(OGRFeatureDefn *poFeatureDefn,
     343             :                    TABFieldType *paeMapInfoNativeFieldTypes = nullptr) override;
     344             :     virtual int AddFieldNative(const char *pszName, TABFieldType eMapInfoType,
     345             :                                int nWidth = 0, int nPrecision = 0,
     346             :                                GBool bIndexed = FALSE, GBool bUnique = FALSE,
     347             :                                int bApproxOK = TRUE) override;
     348             :     int SetSpatialRef(OGRSpatialReference *poSpatialRef) override;
     349             : 
     350             :     OGRErr CreateFeature(TABFeature *poFeature) override;
     351             : 
     352             :     int SetFieldIndexed(int nFieldId) override;
     353             : 
     354             :     ///////////////
     355             :     // semi-private.
     356           0 :     int GetProjInfo(TABProjInfo *poPI) override
     357             :     {
     358           0 :         return m_poMAPFile->GetHeaderBlock()->GetProjInfo(poPI);
     359             :     }
     360             : 
     361             :     int SetProjInfo(TABProjInfo *poPI) override;
     362             :     int SetMIFCoordSys(const char *pszMIFCoordSys) override;
     363             : 
     364             :     int GetFieldIndexNumber(int nFieldId);
     365             :     TABINDFile *GetINDFileRef();
     366             : 
     367             :     TABMAPFile *GetMAPFileRef()
     368             :     {
     369             :         return m_poMAPFile;
     370             :     }
     371             : 
     372             :     int WriteFeature(TABFeature *poFeature);
     373             :     int SetCharset(const char *pszCharset) override;
     374             :     void SetStrictLaundering(bool bStrictLaundering) override;
     375             : #ifdef DEBUG
     376             :     void Dump(FILE *fpOut = nullptr) override;
     377             : #endif
     378             : };
     379             : 
     380             : /*---------------------------------------------------------------------
     381             :  *                      class TABView
     382             :  *
     383             :  * TABView is used to handle special type of .TAB files that are
     384             :  * composed of a number of .TAB datasets linked through some indexed
     385             :  * fields.
     386             :  *
     387             :  * NOTE: The current implementation supports only TABViews composed
     388             :  *       of 2 TABFiles linked through an indexed field of integer type.
     389             :  *       It is unclear if any other type of views could exist anyways.
     390             :  *--------------------------------------------------------------------*/
     391             : class TABView final : public IMapInfoFile
     392             : {
     393             :     CPL_DISALLOW_COPY_ASSIGN(TABView)
     394             : 
     395             :   private:
     396             :     char *m_pszFname;
     397             :     TABAccess m_eAccessMode;
     398             :     char **m_papszTABFile;
     399             :     char *m_pszVersion;
     400             : 
     401             :     char **m_papszTABFnames;
     402             :     TABFile **m_papoTABFiles;
     403             :     int m_numTABFiles;
     404             :     int m_nMainTableIndex;  // The main table is the one that also
     405             :                             // contains the geometries
     406             :     char **m_papszFieldNames;
     407             :     char **m_papszWhereClause;
     408             : 
     409             :     TABRelation *m_poRelation;
     410             :     GBool m_bRelFieldsCreated;
     411             : 
     412             :     ///////////////
     413             :     // Private Read access specific stuff
     414             :     //
     415             :     int ParseTABFile(const char *pszDatasetPath,
     416             :                      GBool bTestOpenNoError = FALSE);
     417             : 
     418             :     int OpenForRead(const char *pszFname, GBool bTestOpenNoError = FALSE);
     419             : 
     420             :     ///////////////
     421             :     // Private Write access specific stuff
     422             :     //
     423             :     int OpenForWrite(const char *pszFname);
     424             :     int WriteTABFile();
     425             : 
     426             :   public:
     427             :     explicit TABView(GDALDataset *poDS);
     428             :     ~TABView() override;
     429             : 
     430           0 :     TABFileClass GetFileClass() override
     431             :     {
     432           0 :         return TABFC_TABView;
     433             :     }
     434             : 
     435           0 :     virtual int Open(const char *pszFname, const char *pszAccess,
     436             :                      GBool bTestOpenNoError = FALSE,
     437             :                      const char *pszCharset = nullptr) override
     438             :     {
     439           0 :         return IMapInfoFile::Open(pszFname, pszAccess, bTestOpenNoError,
     440           0 :                                   pszCharset);
     441             :     }
     442             : 
     443             :     virtual int Open(const char *pszFname, TABAccess eAccess,
     444             :                      GBool bTestOpenNoError = FALSE,
     445             :                      const char *pszCharset = nullptr) override;
     446             :     int Close() override;
     447             : 
     448             :     virtual int
     449             :     SetQuickSpatialIndexMode(GBool bQuickSpatialIndexMode = TRUE) override;
     450             : 
     451           0 :     const char *GetTableName() override
     452             :     {
     453           0 :         return m_poRelation ? m_poRelation->GetFeatureDefn()->GetName() : "";
     454             :     }
     455             : 
     456             :     void ResetReading() override;
     457             :     int TestCapability(const char *pszCap) const override;
     458             :     GIntBig GetFeatureCount(int bForce) override;
     459             :     OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
     460             :                       bool bForce) override;
     461             : 
     462             :     ///////////////
     463             :     // Read access specific stuff
     464             :     //
     465             : 
     466             :     GIntBig GetNextFeatureId(GIntBig nPrevId) override;
     467             :     TABFeature *GetFeatureRef(GIntBig nFeatureId) override;
     468             :     const OGRFeatureDefn *GetLayerDefn() const override;
     469             : 
     470             :     TABFieldType GetNativeFieldType(int nFieldId) override;
     471             : 
     472             :     virtual int GetBounds(double &dXMin, double &dYMin, double &dXMax,
     473             :                           double &dYMax, GBool bForce = TRUE) override;
     474             : 
     475             :     const OGRSpatialReference *GetSpatialRef() const override;
     476             : 
     477             :     virtual int GetFeatureCountByType(int &numPoints, int &numLines,
     478             :                                       int &numRegions, int &numTexts,
     479             :                                       GBool bForce = TRUE) override;
     480             : 
     481             :     GBool IsFieldIndexed(int nFieldId) override;
     482             :     GBool IsFieldUnique(int nFieldId) override;
     483             : 
     484             :     ///////////////
     485             :     // Write access specific stuff
     486             :     //
     487             :     virtual int SetBounds(double dXMin, double dYMin, double dXMax,
     488             :                           double dYMax) override;
     489             :     virtual int
     490             :     SetFeatureDefn(OGRFeatureDefn *poFeatureDefn,
     491             :                    TABFieldType *paeMapInfoNativeFieldTypes = nullptr) override;
     492             :     virtual int AddFieldNative(const char *pszName, TABFieldType eMapInfoType,
     493             :                                int nWidth = 0, int nPrecision = 0,
     494             :                                GBool bIndexed = FALSE, GBool bUnique = FALSE,
     495             :                                int bApproxOK = TRUE) override;
     496             :     int SetSpatialRef(OGRSpatialReference *poSpatialRef) override;
     497             : 
     498             :     OGRErr CreateFeature(TABFeature *poFeature) override;
     499             : 
     500             :     int SetFieldIndexed(int nFieldId) override;
     501             : 
     502             :     ///////////////
     503             :     // semi-private.
     504           0 :     int GetProjInfo(TABProjInfo *poPI) override
     505             :     {
     506           0 :         return m_nMainTableIndex != -1
     507           0 :                    ? m_papoTABFiles[m_nMainTableIndex]->GetProjInfo(poPI)
     508           0 :                    : -1;
     509             :     }
     510             : 
     511           0 :     int SetProjInfo(TABProjInfo *poPI) override
     512             :     {
     513           0 :         return m_nMainTableIndex != -1
     514           0 :                    ? m_papoTABFiles[m_nMainTableIndex]->SetProjInfo(poPI)
     515           0 :                    : -1;
     516             :     }
     517             : 
     518           0 :     int SetMIFCoordSys(const char * /*pszMIFCoordSys*/) override
     519             :     {
     520           0 :         return -1;
     521             :     }
     522             : 
     523             :     int SetCharset(const char *pszCharset) override;
     524             : 
     525             : #ifdef DEBUG
     526             :     void Dump(FILE *fpOut = nullptr) override;
     527             : #endif
     528             : };
     529             : 
     530             : /*---------------------------------------------------------------------
     531             :  *                      class TABSeamless
     532             :  *
     533             :  * TABSeamless is used to handle seamless .TAB files that are
     534             :  * composed of a main .TAB file in which each feature is the MBR of
     535             :  * a base table.
     536             :  *
     537             :  * TABSeamless are supported for read access only.
     538             :  *--------------------------------------------------------------------*/
     539             : class TABSeamless final : public IMapInfoFile
     540             : {
     541             :     CPL_DISALLOW_COPY_ASSIGN(TABSeamless)
     542             : 
     543             :   private:
     544             :     char *m_pszFname;
     545             :     char *m_pszPath;
     546             :     TABAccess m_eAccessMode;
     547             :     OGRFeatureDefn *m_poFeatureDefnRef;
     548             : 
     549             :     TABFile *m_poIndexTable;
     550             :     int m_nTableNameField;
     551             :     int m_nCurBaseTableId;
     552             :     TABFile *m_poCurBaseTable;
     553             :     GBool m_bEOF;
     554             : 
     555             :     ///////////////
     556             :     // Private Read access specific stuff
     557             :     //
     558             :     int OpenForRead(const char *pszFname, GBool bTestOpenNoError = FALSE);
     559             :     int OpenBaseTable(TABFeature *poIndexFeature,
     560             :                       GBool bTestOpenNoError = FALSE);
     561             :     int OpenBaseTable(int nTableId, GBool bTestOpenNoError = FALSE);
     562             :     int OpenNextBaseTable(GBool bTestOpenNoError = FALSE);
     563             :     static GIntBig EncodeFeatureId(int nTableId, int nBaseFeatureId);
     564             :     static int ExtractBaseTableId(GIntBig nEncodedFeatureId);
     565             :     static int ExtractBaseFeatureId(GIntBig nEncodedFeatureId);
     566             : 
     567             :   public:
     568             :     explicit TABSeamless(GDALDataset *poDS);
     569             :     ~TABSeamless() override;
     570             : 
     571           0 :     TABFileClass GetFileClass() override
     572             :     {
     573           0 :         return TABFC_TABSeamless;
     574             :     }
     575             : 
     576           0 :     virtual int Open(const char *pszFname, const char *pszAccess,
     577             :                      GBool bTestOpenNoError = FALSE,
     578             :                      const char *pszCharset = nullptr) override
     579             :     {
     580           0 :         return IMapInfoFile::Open(pszFname, pszAccess, bTestOpenNoError,
     581           0 :                                   pszCharset);
     582             :     }
     583             : 
     584             :     virtual int Open(const char *pszFname, TABAccess eAccess,
     585             :                      GBool bTestOpenNoError = FALSE,
     586             :                      const char *pszCharset = nullptr) override;
     587             :     int Close() override;
     588             : 
     589           0 :     const char *GetTableName() override
     590             :     {
     591           0 :         return m_poFeatureDefnRef ? m_poFeatureDefnRef->GetName() : "";
     592             :     }
     593             : 
     594             :     virtual OGRErr ISetSpatialFilter(int iGeomField,
     595             :                                      const OGRGeometry *poGeom) override;
     596             : 
     597             :     void ResetReading() override;
     598             :     int TestCapability(const char *pszCap) const override;
     599             :     GIntBig GetFeatureCount(int bForce) override;
     600             :     OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
     601             :                       bool bForce) override;
     602             : 
     603             :     ///////////////
     604             :     // Read access specific stuff
     605             :     //
     606             : 
     607             :     GIntBig GetNextFeatureId(GIntBig nPrevId) override;
     608             :     TABFeature *GetFeatureRef(GIntBig nFeatureId) override;
     609             :     const OGRFeatureDefn *GetLayerDefn() const override;
     610             : 
     611             :     TABFieldType GetNativeFieldType(int nFieldId) override;
     612             : 
     613             :     virtual int GetBounds(double &dXMin, double &dYMin, double &dXMax,
     614             :                           double &dYMax, GBool bForce = TRUE) override;
     615             : 
     616             :     const OGRSpatialReference *GetSpatialRef() const override;
     617             : 
     618             :     virtual int GetFeatureCountByType(int &numPoints, int &numLines,
     619             :                                       int &numRegions, int &numTexts,
     620             :                                       GBool bForce = TRUE) override;
     621             : 
     622             :     GBool IsFieldIndexed(int nFieldId) override;
     623             :     GBool IsFieldUnique(int nFieldId) override;
     624             : 
     625             :     ///////////////
     626             :     // Write access specific stuff
     627             :     //
     628           0 :     virtual int SetBounds(CPL_UNUSED double dXMin, CPL_UNUSED double dYMin,
     629             :                           CPL_UNUSED double dXMax,
     630             :                           CPL_UNUSED double dYMax) override
     631             :     {
     632           0 :         return -1;
     633             :     }
     634             : 
     635           0 :     virtual int SetFeatureDefn(
     636             :         CPL_UNUSED OGRFeatureDefn *poFeatureDefn,
     637             :         CPL_UNUSED TABFieldType *paeMapInfoNativeFieldTypes = nullptr) override
     638             :     {
     639           0 :         return -1;
     640             :     }
     641             : 
     642           0 :     virtual int AddFieldNative(CPL_UNUSED const char *pszName,
     643             :                                CPL_UNUSED TABFieldType eMapInfoType,
     644             :                                CPL_UNUSED int nWidth = 0,
     645             :                                CPL_UNUSED int nPrecision = 0,
     646             :                                CPL_UNUSED GBool bIndexed = FALSE,
     647             :                                CPL_UNUSED GBool bUnique = FALSE,
     648             :                                CPL_UNUSED int bApproxOK = TRUE) override
     649             :     {
     650           0 :         return -1;
     651             :     }
     652             : 
     653             :     virtual int
     654           0 :     SetSpatialRef(CPL_UNUSED OGRSpatialReference *poSpatialRef) override
     655             :     {
     656           0 :         return -1;
     657             :     }
     658             : 
     659           0 :     OGRErr CreateFeature(CPL_UNUSED TABFeature *poFeature) override
     660             :     {
     661           0 :         return OGRERR_UNSUPPORTED_OPERATION;
     662             :     }
     663             : 
     664           0 :     int SetFieldIndexed(CPL_UNUSED int nFieldId) override
     665             :     {
     666           0 :         return -1;
     667             :     }
     668             : 
     669             :     ///////////////
     670             :     // semi-private.
     671           0 :     int GetProjInfo(TABProjInfo *poPI) override
     672             :     {
     673           0 :         return m_poIndexTable ? m_poIndexTable->GetProjInfo(poPI) : -1;
     674             :     }
     675             : 
     676           0 :     int SetProjInfo(CPL_UNUSED TABProjInfo *poPI) override
     677             :     {
     678           0 :         return -1;
     679             :     }
     680             : 
     681           0 :     int SetMIFCoordSys(const char * /*pszMIFCoordSys*/) override
     682             :     {
     683           0 :         return -1;
     684             :     }
     685             : 
     686             : #ifdef DEBUG
     687             :     void Dump(FILE *fpOut = nullptr) override;
     688             : #endif
     689             : };
     690             : 
     691             : /*---------------------------------------------------------------------
     692             :  *                      class MIFFile
     693             :  *
     694             :  * The main class for (MID/MIF) datasets.  External programs should use this
     695             :  * class to open a (MID/MIF) dataset and read/write features from/to it.
     696             :  *
     697             :  *--------------------------------------------------------------------*/
     698             : class MIFFile final : public IMapInfoFile
     699             : {
     700             :     CPL_DISALLOW_COPY_ASSIGN(MIFFile)
     701             : 
     702             :   private:
     703             :     char *m_pszFname;
     704             :     TABAccess m_eAccessMode;
     705             :     int m_nVersion; /* Dataset version: 300, 450, 600, 900, etc. */
     706             :     char *m_pszDelimiter;
     707             :     char *m_pszUnique;
     708             :     char *m_pszIndex;
     709             :     char *m_pszCoordSys;
     710             : 
     711             :     TABFieldType *m_paeFieldType;
     712             :     GBool *m_pabFieldIndexed;
     713             :     GBool *m_pabFieldUnique;
     714             : 
     715             :     double m_dfXMultiplier;
     716             :     double m_dfYMultiplier;
     717             :     double m_dfXDisplacement;
     718             :     double m_dfYDisplacement;
     719             : 
     720             :     /* these are the projection bounds, possibly much broader than extents */
     721             :     double m_dXMin;
     722             :     double m_dYMin;
     723             :     double m_dXMax;
     724             :     double m_dYMax;
     725             : 
     726             :     /* extents, as cached by MIFFile::PreParseFile() */
     727             :     int m_bExtentsSet;
     728             :     OGREnvelope m_sExtents{};
     729             : 
     730             :     int m_nPoints;
     731             :     int m_nLines;
     732             :     int m_nRegions;
     733             :     int m_nTexts;
     734             : 
     735             :     int m_nPreloadedId;        // preloaded mif line is for this feature id
     736             :     MIDDATAFile *m_poMIDFile;  // Mid file
     737             :     MIDDATAFile *m_poMIFFile;  // Mif File
     738             : 
     739             :     OGRFeatureDefn *m_poDefn;
     740             :     mutable OGRSpatialReference *m_poSpatialRef;
     741             : 
     742             :     int m_nFeatureCount;
     743             :     int m_nWriteFeatureId;
     744             :     int m_nAttribute;
     745             : 
     746             :     ///////////////
     747             :     // Private Read access specific stuff
     748             :     //
     749             :     int ReadFeatureDefn();
     750             :     int ParseMIFHeader(int *pbIsEmpty);
     751             :     void PreParseFile();
     752             :     int AddFields(const char *pszLine);
     753             :     int GotoFeature(int nFeatureId);
     754             : 
     755             :     ///////////////
     756             :     // Private Write access specific stuff
     757             :     //
     758             :     GBool m_bPreParsed;
     759             :     GBool m_bHeaderWrote;
     760             : 
     761             :     int WriteMIFHeader();
     762             :     void UpdateExtents(double dfX, double dfY);
     763             : 
     764             :   public:
     765             :     explicit MIFFile(GDALDataset *poDS);
     766             :     ~MIFFile() override;
     767             : 
     768          84 :     TABFileClass GetFileClass() override
     769             :     {
     770          84 :         return TABFC_MIFFile;
     771             :     }
     772             : 
     773           0 :     virtual int Open(const char *pszFname, const char *pszAccess,
     774             :                      GBool bTestOpenNoError = FALSE,
     775             :                      const char *pszCharset = nullptr) override
     776             :     {
     777           0 :         return IMapInfoFile::Open(pszFname, pszAccess, bTestOpenNoError,
     778           0 :                                   pszCharset);
     779             :     }
     780             : 
     781             :     virtual int Open(const char *pszFname, TABAccess eAccess,
     782             :                      GBool bTestOpenNoError = FALSE,
     783             :                      const char *pszCharset = nullptr) override;
     784             :     int Close() override;
     785             : 
     786           0 :     const char *GetTableName() override
     787             :     {
     788           0 :         return m_poDefn ? m_poDefn->GetName() : "";
     789             :     }
     790             : 
     791             :     int TestCapability(const char *pszCap) const override;
     792             :     GIntBig GetFeatureCount(int bForce) override;
     793             :     void ResetReading() override;
     794             :     OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
     795             :                       bool bForce) override;
     796             : 
     797             :     ///////////////
     798             :     // Read access specific stuff
     799             :     //
     800             : 
     801             :     GIntBig GetNextFeatureId(GIntBig nPrevId) override;
     802             :     TABFeature *GetFeatureRef(GIntBig nFeatureId) override;
     803             :     const OGRFeatureDefn *GetLayerDefn() const override;
     804             : 
     805             :     TABFieldType GetNativeFieldType(int nFieldId) override;
     806             : 
     807             :     virtual int GetBounds(double &dXMin, double &dYMin, double &dXMax,
     808             :                           double &dYMax, GBool bForce = TRUE) override;
     809             : 
     810             :     const OGRSpatialReference *GetSpatialRef() const override;
     811             : 
     812             :     virtual int GetFeatureCountByType(int &numPoints, int &numLines,
     813             :                                       int &numRegions, int &numTexts,
     814             :                                       GBool bForce = TRUE) override;
     815             : 
     816             :     GBool IsFieldIndexed(int nFieldId) override;
     817             :     GBool IsFieldUnique(int nFieldId) override;
     818             : 
     819             :     int GetVersion()
     820             :     {
     821             :         return m_nVersion;
     822             :     }
     823             : 
     824             :     ///////////////
     825             :     // Write access specific stuff
     826             :     //
     827             :     virtual int SetBounds(double dXMin, double dYMin, double dXMax,
     828             :                           double dYMax) override;
     829             :     virtual int
     830             :     SetFeatureDefn(OGRFeatureDefn *poFeatureDefn,
     831             :                    TABFieldType *paeMapInfoNativeFieldTypes = nullptr) override;
     832             :     virtual int AddFieldNative(const char *pszName, TABFieldType eMapInfoType,
     833             :                                int nWidth = 0, int nPrecision = 0,
     834             :                                GBool bIndexed = FALSE, GBool bUnique = FALSE,
     835             :                                int bApproxOK = TRUE) override;
     836             :     /* TODO */
     837             :     int SetSpatialRef(OGRSpatialReference *poSpatialRef) override;
     838             : 
     839             :     OGRErr CreateFeature(TABFeature *poFeature) override;
     840             : 
     841             :     int SetFieldIndexed(int nFieldId) override;
     842             : 
     843             :     ///////////////
     844             :     // semi-private.
     845           0 :     int GetProjInfo(TABProjInfo * /*poPI*/) override
     846             :     {
     847           0 :         return -1;
     848             :     }
     849             : 
     850             :     /*  { return m_poMAPFile->GetHeaderBlock()->GetProjInfo( poPI ); }*/
     851           0 :     int SetProjInfo(TABProjInfo * /*poPI*/) override
     852             :     {
     853           0 :         return -1;
     854             :     }
     855             : 
     856             :     /*  { return m_poMAPFile->GetHeaderBlock()->SetProjInfo( poPI ); }*/
     857             :     int SetMIFCoordSys(const char *pszMIFCoordSys) override;
     858             :     int SetCharset(const char *pszCharset) override;
     859             :     void SetStrictLaundering(bool bStrictLaundering) override;
     860             : #ifdef DEBUG
     861           0 :     void Dump(FILE * /*fpOut*/ = nullptr) override
     862             :     {
     863           0 :     }
     864             : #endif
     865             : };
     866             : 
     867             : /*---------------------------------------------------------------------
     868             :  * Define some error codes specific to this lib.
     869             :  *--------------------------------------------------------------------*/
     870             : #define TAB_WarningFeatureTypeNotSupported 501
     871             : #define TAB_WarningInvalidFieldName 502
     872             : #define TAB_WarningBoundsOverflow 503
     873             : 
     874             : /*---------------------------------------------------------------------
     875             :  * Codes for the feature classes
     876             :  *--------------------------------------------------------------------*/
     877             : typedef enum
     878             : {
     879             :     TABFCNoGeomFeature = 0,
     880             :     TABFCPoint = 1,
     881             :     TABFCFontPoint = 2,
     882             :     TABFCCustomPoint = 3,
     883             :     TABFCText = 4,
     884             :     TABFCPolyline = 5,
     885             :     TABFCArc = 6,
     886             :     TABFCRegion = 7,
     887             :     TABFCRectangle = 8,
     888             :     TABFCEllipse = 9,
     889             :     TABFCMultiPoint = 10,
     890             :     TABFCCollection = 11,
     891             :     TABFCDebugFeature
     892             : } TABFeatureClass;
     893             : 
     894             : /*---------------------------------------------------------------------
     895             :  * Definitions for text attributes
     896             :  *--------------------------------------------------------------------*/
     897             : typedef enum TABTextJust_t
     898             : {
     899             :     TABTJLeft = 0,  // Default: Left Justification
     900             :     TABTJCenter,
     901             :     TABTJRight
     902             : } TABTextJust;
     903             : 
     904             : typedef enum TABTextSpacing_t
     905             : {
     906             :     TABTSSingle = 0,  // Default: Single spacing
     907             :     TABTS1_5,         // 1.5
     908             :     TABTSDouble
     909             : } TABTextSpacing;
     910             : 
     911             : typedef enum TABTextLineType_t
     912             : {
     913             :     TABTLNoLine = 0,  // Default: No line
     914             :     TABTLSimple,
     915             :     TABTLArrow
     916             : } TABTextLineType;
     917             : 
     918             : typedef enum TABFontStyle_t  // Can be OR'ed
     919             : {                            // except box and halo are mutually exclusive
     920             :     TABFSNone = 0,
     921             :     TABFSBold = 0x0001,
     922             :     TABFSItalic = 0x0002,
     923             :     TABFSUnderline = 0x0004,
     924             :     TABFSStrikeout = 0x0008,
     925             :     TABFSOutline = 0x0010,
     926             :     TABFSShadow = 0x0020,
     927             :     TABFSInverse = 0x0040,
     928             :     TABFSBlink = 0x0080,
     929             :     TABFSBox = 0x0100,      // See note about box vs halo below.
     930             :     TABFSHalo = 0x0200,     // MIF uses 256, see MIF docs, App.A
     931             :     TABFSAllCaps = 0x0400,  // MIF uses 512
     932             :     TABFSExpanded = 0x0800  // MIF uses 1024
     933             : } TABFontStyle;
     934             : 
     935             : /* TABFontStyle enum notes:
     936             :  *
     937             :  * The enumeration values above correspond to the values found in a .MAP
     938             :  * file. However, they differ a little from what is found in a MIF file:
     939             :  * Values 0x01 to 0x80 are the same in .MIF and .MAP files.
     940             :  * Values 0x200 to 0x800 in .MAP are 0x100 to 0x400 in .MIF
     941             :  *
     942             :  * What about TABFSBox (0x100) ?
     943             :  * TABFSBox is stored just like the other styles in .MAP files but it is not
     944             :  * explicitly stored in a MIF file.
     945             :  * If a .MIF FONT() clause contains the optional BG color, then this implies
     946             :  * that either Halo or Box was set.  Thus if TABFSHalo (value 256 in MIF)
     947             :  * is not set in the style, then this implies that TABFSBox should be set.
     948             :  */
     949             : 
     950             : typedef enum TABCustSymbStyle_t  // Can be OR'ed
     951             : {
     952             :     TABCSNone = 0,          // Transparent BG, use default colors
     953             :     TABCSBGOpaque = 0x01,   // White pixels are opaque
     954             :     TABCSApplyColor = 0x02  // non-white pixels drawn using symbol color
     955             : } TABCustSymbStyle;
     956             : 
     957             : /*=====================================================================
     958             :   Base classes to be used to add supported drawing tools to each feature type
     959             :  =====================================================================*/
     960             : 
     961        7777 : class ITABFeaturePen /* non final */
     962             : {
     963             :   protected:
     964             :     int m_nPenDefIndex;
     965             :     TABPenDef m_sPenDef;
     966             : 
     967             :   public:
     968             :     ITABFeaturePen();
     969             : 
     970             :     virtual ~ITABFeaturePen();
     971             : 
     972             :     int GetPenDefIndex() const
     973             :     {
     974             :         return m_nPenDefIndex;
     975             :     }
     976             : 
     977           0 :     TABPenDef *GetPenDefRef()
     978             :     {
     979           0 :         return &m_sPenDef;
     980             :     }
     981             : 
     982             :     const TABPenDef *GetPenDefRef() const
     983             :     {
     984             :         return &m_sPenDef;
     985             :     }
     986             : 
     987             :     GByte GetPenWidthPixel() const;
     988             :     double GetPenWidthPoint() const;
     989             :     int GetPenWidthMIF() const;
     990             : 
     991         240 :     GByte GetPenPattern() const
     992             :     {
     993         240 :         return m_sPenDef.nLinePattern;
     994             :     }
     995             : 
     996          21 :     GInt32 GetPenColor() const
     997             :     {
     998          21 :         return m_sPenDef.rgbColor;
     999             :     }
    1000             : 
    1001             :     void SetPenWidthPixel(GByte val);
    1002             :     void SetPenWidthPoint(double val);
    1003             :     void SetPenWidthMIF(int val);
    1004             : 
    1005        2463 :     void SetPenPattern(GByte val)
    1006             :     {
    1007        2463 :         m_sPenDef.nLinePattern = val;
    1008        2463 :     }
    1009             : 
    1010        2464 :     void SetPenColor(GInt32 clr)
    1011             :     {
    1012        2464 :         m_sPenDef.rgbColor = clr;
    1013        2464 :     }
    1014             : 
    1015             :     const char *GetPenStyleString() const;
    1016             :     void SetPenFromStyleString(const char *pszStyleString);
    1017             : 
    1018             :     void DumpPenDef(FILE *fpOut = nullptr);
    1019             : };
    1020             : 
    1021        2540 : class ITABFeatureBrush /* non final */
    1022             : {
    1023             :   protected:
    1024             :     int m_nBrushDefIndex;
    1025             :     TABBrushDef m_sBrushDef;
    1026             : 
    1027             :   public:
    1028             :     ITABFeatureBrush();
    1029             : 
    1030             :     virtual ~ITABFeatureBrush();
    1031             : 
    1032             :     int GetBrushDefIndex() const
    1033             :     {
    1034             :         return m_nBrushDefIndex;
    1035             :     }
    1036             : 
    1037           0 :     TABBrushDef *GetBrushDefRef()
    1038             :     {
    1039           0 :         return &m_sBrushDef;
    1040             :     }
    1041             : 
    1042             :     const TABBrushDef *GetBrushDefRef() const
    1043             :     {
    1044             :         return &m_sBrushDef;
    1045             :     }
    1046             : 
    1047          21 :     GInt32 GetBrushFGColor() const
    1048             :     {
    1049          21 :         return m_sBrushDef.rgbFGColor;
    1050             :     }
    1051             : 
    1052          21 :     GInt32 GetBrushBGColor() const
    1053             :     {
    1054          21 :         return m_sBrushDef.rgbBGColor;
    1055             :     }
    1056             : 
    1057          42 :     GByte GetBrushPattern() const
    1058             :     {
    1059          42 :         return m_sBrushDef.nFillPattern;
    1060             :     }
    1061             : 
    1062          75 :     GByte GetBrushTransparent() const
    1063             :     {
    1064          75 :         return m_sBrushDef.bTransparentFill;
    1065             :     }
    1066             : 
    1067        1575 :     void SetBrushFGColor(GInt32 clr)
    1068             :     {
    1069        1575 :         m_sBrushDef.rgbFGColor = clr;
    1070        1575 :     }
    1071             : 
    1072        1567 :     void SetBrushBGColor(GInt32 clr)
    1073             :     {
    1074        1567 :         m_sBrushDef.rgbBGColor = clr;
    1075        1567 :     }
    1076             : 
    1077        1575 :     void SetBrushPattern(GByte val)
    1078             :     {
    1079        1575 :         m_sBrushDef.nFillPattern = val;
    1080        1575 :     }
    1081             : 
    1082           8 :     void SetBrushTransparent(GByte val)
    1083             :     {
    1084           8 :         m_sBrushDef.bTransparentFill = val;
    1085           8 :     }
    1086             : 
    1087             :     const char *GetBrushStyleString() const;
    1088             :     void SetBrushFromStyleString(const char *pszStyleString);
    1089             : 
    1090             :     void DumpBrushDef(FILE *fpOut = nullptr);
    1091             : };
    1092             : 
    1093        1638 : class ITABFeatureFont /* non final */
    1094             : {
    1095             :   protected:
    1096             :     int m_nFontDefIndex;
    1097             :     TABFontDef m_sFontDef;
    1098             : 
    1099             :   public:
    1100             :     ITABFeatureFont();
    1101             : 
    1102             :     virtual ~ITABFeatureFont();
    1103             : 
    1104             :     int GetFontDefIndex() const
    1105             :     {
    1106             :         return m_nFontDefIndex;
    1107             :     }
    1108             : 
    1109           0 :     TABFontDef *GetFontDefRef()
    1110             :     {
    1111           0 :         return &m_sFontDef;
    1112             :     }
    1113             : 
    1114             :     const TABFontDef *GetFontDefRef() const
    1115             :     {
    1116             :         return &m_sFontDef;
    1117             :     }
    1118             : 
    1119          38 :     const char *GetFontNameRef() const
    1120             :     {
    1121          38 :         return m_sFontDef.szFontName;
    1122             :     }
    1123             : 
    1124             :     void SetFontName(const char *pszName);
    1125             : 
    1126             :     void DumpFontDef(FILE *fpOut = nullptr);
    1127             : };
    1128             : 
    1129             : class ITABFeatureSymbol /* non final */
    1130             : {
    1131             :   protected:
    1132             :     int m_nSymbolDefIndex;
    1133             :     TABSymbolDef m_sSymbolDef;
    1134             : 
    1135             :   public:
    1136             :     ITABFeatureSymbol();
    1137             : 
    1138      566233 :     virtual ~ITABFeatureSymbol() = default;
    1139             : 
    1140             :     int GetSymbolDefIndex() const
    1141             :     {
    1142             :         return m_nSymbolDefIndex;
    1143             :     }
    1144             : 
    1145           4 :     TABSymbolDef *GetSymbolDefRef()
    1146             :     {
    1147           4 :         return &m_sSymbolDef;
    1148             :     }
    1149             : 
    1150             :     const TABSymbolDef *GetSymbolDefRef() const
    1151             :     {
    1152             :         return &m_sSymbolDef;
    1153             :     }
    1154             : 
    1155          82 :     GInt16 GetSymbolNo() const
    1156             :     {
    1157          82 :         return m_sSymbolDef.nSymbolNo;
    1158             :     }
    1159             : 
    1160          82 :     GInt16 GetSymbolSize() const
    1161             :     {
    1162          82 :         return m_sSymbolDef.nPointSize;
    1163             :     }
    1164             : 
    1165          82 :     GInt32 GetSymbolColor() const
    1166             :     {
    1167          82 :         return m_sSymbolDef.rgbColor;
    1168             :     }
    1169             : 
    1170         771 :     void SetSymbolNo(GInt16 val)
    1171             :     {
    1172         771 :         m_sSymbolDef.nSymbolNo = val;
    1173         771 :     }
    1174             : 
    1175        1451 :     void SetSymbolSize(GInt16 val)
    1176             :     {
    1177        1451 :         m_sSymbolDef.nPointSize = val;
    1178        1451 :     }
    1179             : 
    1180        1451 :     void SetSymbolColor(GInt32 clr)
    1181             :     {
    1182        1451 :         m_sSymbolDef.rgbColor = clr;
    1183        1451 :     }
    1184             : 
    1185             :     static TABFeatureClass GetSymbolFeatureClass(const char *pszStyleString);
    1186             :     virtual const char *GetSymbolStyleString(double dfAngle = 0.0) const;
    1187             :     void SetSymbolFromStyleString(const char *pszStyleString);
    1188             :     virtual void SetSymbolFromStyle(OGRStyleSymbol *poSymbolStyle);
    1189             : 
    1190             :     void DumpSymbolDef(FILE *fpOut = nullptr);
    1191             : };
    1192             : 
    1193             : /*=====================================================================
    1194             :                         Feature Classes
    1195             :  =====================================================================*/
    1196             : 
    1197             : /*---------------------------------------------------------------------
    1198             :  *                      class TABFeature
    1199             :  *
    1200             :  * Extend the OGRFeature to support MapInfo specific extensions related
    1201             :  * to geometry types, representation strings, etc.
    1202             :  *
    1203             :  * TABFeature will be used as a base class for all the feature classes.
    1204             :  *
    1205             :  * This class will also be used to instantiate objects with no Geometry
    1206             :  * (i.e. type TAB_GEOM_NONE) which is a valid case in MapInfo.
    1207             :  *
    1208             :  * The logic to read/write the object from/to the .DAT and .MAP files is also
    1209             :  * implemented as part of this class and derived classes.
    1210             :  *--------------------------------------------------------------------*/
    1211             : class TABFeature /* non final*/ : public OGRFeature
    1212             : {
    1213             :   protected:
    1214             :     TABGeomType m_nMapInfoType;
    1215             : 
    1216             :     double m_dXMin;
    1217             :     double m_dYMin;
    1218             :     double m_dXMax;
    1219             :     double m_dYMax;
    1220             : 
    1221             :     GBool m_bDeletedFlag;
    1222             : 
    1223             :     void CopyTABFeatureBase(TABFeature *poDestFeature);
    1224             : 
    1225             :     // Compr. Origin is set for TAB files by ValidateCoordType()
    1226             :     GInt32 m_nXMin;
    1227             :     GInt32 m_nYMin;
    1228             :     GInt32 m_nXMax;
    1229             :     GInt32 m_nYMax;
    1230             :     GInt32 m_nComprOrgX;
    1231             :     GInt32 m_nComprOrgY;
    1232             : 
    1233             :     virtual int UpdateMBR(TABMAPFile *poMapFile = nullptr);
    1234             : 
    1235             :   public:
    1236             :     explicit TABFeature(const OGRFeatureDefn *poDefnIn);
    1237             :     ~TABFeature() override;
    1238             : 
    1239             :     static TABFeature *CreateFromMapInfoType(int nMapInfoType,
    1240             :                                              OGRFeatureDefn *poDefn);
    1241             : 
    1242             :     virtual TABFeature *
    1243             :     CloneTABFeature(const OGRFeatureDefn *pNewDefn = nullptr);
    1244             : 
    1245          82 :     virtual TABFeatureClass GetFeatureClass()
    1246             :     {
    1247          82 :         return TABFCNoGeomFeature;
    1248             :     }
    1249             : 
    1250           0 :     virtual TABGeomType GetMapInfoType()
    1251             :     {
    1252           0 :         return m_nMapInfoType;
    1253             :     }
    1254             : 
    1255             :     virtual TABGeomType
    1256          60 :     ValidateMapInfoType(CPL_UNUSED TABMAPFile *poMapFile = nullptr)
    1257             :     {
    1258          60 :         m_nMapInfoType = TAB_GEOM_NONE;
    1259          60 :         return m_nMapInfoType;
    1260             :     }
    1261             : 
    1262             :     GBool IsRecordDeleted()
    1263             :     {
    1264             :         return m_bDeletedFlag;
    1265             :     }
    1266             : 
    1267      551214 :     void SetRecordDeleted(GBool bDeleted)
    1268             :     {
    1269      551214 :         m_bDeletedFlag = bDeleted;
    1270      551214 :     }
    1271             : 
    1272             :     /*-----------------------------------------------------------------
    1273             :      * TAB Support
    1274             :      *----------------------------------------------------------------*/
    1275             : 
    1276             :     virtual int ReadRecordFromDATFile(TABDATFile *poDATFile);
    1277             :     virtual int
    1278             :     ReadGeometryFromMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1279             :                             GBool bCoordDataOnly = FALSE,
    1280             :                             TABMAPCoordBlock **ppoCoordBlock = nullptr);
    1281             : 
    1282             :     virtual int WriteRecordToDATFile(TABDATFile *poDATFile,
    1283             :                                      TABINDFile *poINDFile, int *panIndexNo);
    1284             :     virtual int
    1285             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1286             :                            GBool bCoordDataOnly = FALSE,
    1287             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr);
    1288             :     GBool ValidateCoordType(TABMAPFile *poMapFile);
    1289             :     void ForceCoordTypeAndOrigin(TABGeomType nMapInfoType, GBool bCompr,
    1290             :                                  GInt32 nComprOrgX, GInt32 nComprOrgY,
    1291             :                                  GInt32 nXMin, GInt32 nYMin, GInt32 nXMax,
    1292             :                                  GInt32 nYMax);
    1293             : 
    1294             :     /*-----------------------------------------------------------------
    1295             :      * Mid/Mif Support
    1296             :      *----------------------------------------------------------------*/
    1297             : 
    1298             :     virtual int ReadRecordFromMIDFile(MIDDATAFile *fp);
    1299             :     virtual int ReadGeometryFromMIFFile(MIDDATAFile *fp);
    1300             : 
    1301             :     virtual int WriteRecordToMIDFile(MIDDATAFile *fp);
    1302             :     virtual int WriteGeometryToMIFFile(MIDDATAFile *fp);
    1303             : 
    1304             :     void ReadMIFParameters(MIDDATAFile *fp);
    1305             :     void WriteMIFParameters(MIDDATAFile *fp);
    1306             : 
    1307             :     /*-----------------------------------------------------------------
    1308             :      *----------------------------------------------------------------*/
    1309             : 
    1310             :     void SetMBR(double dXMin, double dYMin, double dXMax, double dYMax);
    1311             :     void GetMBR(double &dXMin, double &dYMin, double &dXMax, double &dYMax);
    1312             :     void SetIntMBR(GInt32 nXMin, GInt32 nYMin, GInt32 nXMax, GInt32 nYMax);
    1313             :     void GetIntMBR(GInt32 &nXMin, GInt32 &nYMin, GInt32 &nXMax, GInt32 &nYMax);
    1314             : 
    1315             :     virtual void DumpMID(FILE *fpOut = nullptr);
    1316             :     virtual void DumpMIF(FILE *fpOut = nullptr);
    1317             : };
    1318             : 
    1319             : /*---------------------------------------------------------------------
    1320             :  *                      class TABPoint
    1321             :  *
    1322             :  * Feature class to handle old style MapInfo point symbols:
    1323             :  *
    1324             :  *     TAB_GEOM_SYMBOL_C        0x01
    1325             :  *     TAB_GEOM_SYMBOL          0x02
    1326             :  *
    1327             :  * Feature geometry will be a OGRPoint
    1328             :  *
    1329             :  * The symbol number is in the range [31..67], with 31=None and corresponds
    1330             :  * to one of the 35 predefined "Old MapInfo Symbols"
    1331             :  *
    1332             :  * NOTE: This class is also used as a base class for the other point
    1333             :  * symbol types TABFontPoint and TABCustomPoint.
    1334             :  *--------------------------------------------------------------------*/
    1335             : class TABPoint : public TABFeature, public ITABFeatureSymbol
    1336             : {
    1337             :     CPL_DISALLOW_COPY_ASSIGN(TABPoint)
    1338             : 
    1339             :   public:
    1340             :     explicit TABPoint(const OGRFeatureDefn *poDefnIn);
    1341             :     ~TABPoint() override;
    1342             : 
    1343       15441 :     TABFeatureClass GetFeatureClass() override
    1344             :     {
    1345       15441 :         return TABFCPoint;
    1346             :     }
    1347             : 
    1348             :     virtual TABGeomType
    1349             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    1350             : 
    1351             :     virtual TABFeature *
    1352             :     CloneTABFeature(const OGRFeatureDefn *poNewDefn = nullptr) override;
    1353             : 
    1354             :     double GetX();
    1355             :     double GetY();
    1356             : 
    1357             :     virtual int ReadGeometryFromMAPFile(
    1358             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1359             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1360             :     virtual int
    1361             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1362             :                            GBool bCoordDataOnly = FALSE,
    1363             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1364             : 
    1365             :     int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1366             :     int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1367             : 
    1368             :     const char *GetStyleString() const override;
    1369             : 
    1370             :     void DumpMIF(FILE *fpOut = nullptr) override;
    1371             : };
    1372             : 
    1373             : /*---------------------------------------------------------------------
    1374             :  *                      class TABFontPoint
    1375             :  *
    1376             :  * Feature class to handle MapInfo Font Point Symbol types:
    1377             :  *
    1378             :  *     TAB_GEOM_FONTSYMBOL_C    0x28
    1379             :  *     TAB_GEOM_FONTSYMBOL      0x29
    1380             :  *
    1381             :  * Feature geometry will be a OGRPoint
    1382             :  *
    1383             :  * The symbol number refers to a character code in the specified Windows
    1384             :  * Font (e.g. "Windings").
    1385             :  *--------------------------------------------------------------------*/
    1386             : class TABFontPoint final : public TABPoint, public ITABFeatureFont
    1387             : {
    1388             :     CPL_DISALLOW_COPY_ASSIGN(TABFontPoint)
    1389             : 
    1390             :   protected:
    1391             :     double m_dAngle;
    1392             :     GInt16 m_nFontStyle;  // Bold/shadow/halo/etc.
    1393             : 
    1394             :   public:
    1395             :     explicit TABFontPoint(const OGRFeatureDefn *poDefnIn);
    1396             :     ~TABFontPoint() override;
    1397             : 
    1398         637 :     TABFeatureClass GetFeatureClass() override
    1399             :     {
    1400         637 :         return TABFCFontPoint;
    1401             :     }
    1402             : 
    1403             :     virtual TABFeature *
    1404             :     CloneTABFeature(const OGRFeatureDefn *poNewDefn = nullptr) override;
    1405             : 
    1406             :     virtual int ReadGeometryFromMAPFile(
    1407             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1408             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1409             :     virtual int
    1410             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1411             :                            GBool bCoordDataOnly = FALSE,
    1412             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1413             : 
    1414             :     int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1415             :     int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1416             : 
    1417             :     virtual const char *
    1418             :     GetSymbolStyleString(double dfAngle = 0.0) const override;
    1419             :     const char *GetStyleString() const override;
    1420             :     void SetSymbolFromStyle(OGRStyleSymbol *poSymbolStyle) override;
    1421             : 
    1422             :     GBool QueryFontStyle(TABFontStyle eStyleToQuery);
    1423             :     void ToggleFontStyle(TABFontStyle eStyleToToggle, GBool bStatus);
    1424             : 
    1425             :     int GetFontStyleMIFValue();
    1426             :     void SetFontStyleMIFValue(int nStyle);
    1427             : 
    1428           0 :     int GetFontStyleTABValue()
    1429             :     {
    1430           0 :         return m_nFontStyle;
    1431             :     }
    1432             : 
    1433           0 :     void SetFontStyleTABValue(int nStyle)
    1434             :     {
    1435           0 :         m_nFontStyle = static_cast<GInt16>(nStyle);
    1436           0 :     }
    1437             : 
    1438             :     // GetSymbolAngle(): Return angle in degrees counterclockwise
    1439           7 :     double GetSymbolAngle() const
    1440             :     {
    1441           7 :         return m_dAngle;
    1442             :     }
    1443             : 
    1444             :     void SetSymbolAngle(double dAngle);
    1445             : };
    1446             : 
    1447             : /*---------------------------------------------------------------------
    1448             :  *                      class TABCustomPoint
    1449             :  *
    1450             :  * Feature class to handle MapInfo Custom Point Symbol (Bitmap) types:
    1451             :  *
    1452             :  *     TAB_GEOM_CUSTOMSYMBOL_C  0x2b
    1453             :  *     TAB_GEOM_CUSTOMSYMBOL    0x2c
    1454             :  *
    1455             :  * Feature geometry will be a OGRPoint
    1456             :  *
    1457             :  * The symbol name is the name of a BMP file stored in the "CustSymb"
    1458             :  * directory (e.g. "arrow.BMP").  The symbol number has no meaning for
    1459             :  * this symbol type.
    1460             :  *--------------------------------------------------------------------*/
    1461             : class TABCustomPoint final : public TABPoint, public ITABFeatureFont
    1462             : {
    1463             :   protected:
    1464             :     GByte m_nCustomStyle;  // Show BG/Apply Color
    1465             : 
    1466             :   public:
    1467             :     GByte m_nUnknown_;
    1468             : 
    1469             :   public:
    1470             :     explicit TABCustomPoint(const OGRFeatureDefn *poDefnIn);
    1471             :     ~TABCustomPoint() override;
    1472             : 
    1473         680 :     TABFeatureClass GetFeatureClass() override
    1474             :     {
    1475         680 :         return TABFCCustomPoint;
    1476             :     }
    1477             : 
    1478             :     virtual TABFeature *
    1479             :     CloneTABFeature(const OGRFeatureDefn *poNewDefn = nullptr) override;
    1480             : 
    1481             :     virtual int ReadGeometryFromMAPFile(
    1482             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1483             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1484             :     virtual int
    1485             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1486             :                            GBool bCoordDataOnly = FALSE,
    1487             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1488             : 
    1489             :     int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1490             :     int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1491             : 
    1492             :     virtual const char *
    1493             :     GetSymbolStyleString(double dfAngle = 0.0) const override;
    1494             :     const char *GetStyleString() const override;
    1495             :     void SetSymbolFromStyle(OGRStyleSymbol *poSymbolStyle) override;
    1496             : 
    1497          21 :     const char *GetSymbolNameRef() const
    1498             :     {
    1499          21 :         return GetFontNameRef();
    1500             :     }
    1501             : 
    1502           2 :     void SetSymbolName(const char *pszName)
    1503             :     {
    1504           2 :         SetFontName(pszName);
    1505           2 :     }
    1506             : 
    1507           0 :     GByte GetCustomSymbolStyle()
    1508             :     {
    1509           0 :         return m_nCustomStyle;
    1510             :     }
    1511             : 
    1512           2 :     void SetCustomSymbolStyle(GByte nStyle)
    1513             :     {
    1514           2 :         m_nCustomStyle = nStyle;
    1515           2 :     }
    1516             : };
    1517             : 
    1518             : /*---------------------------------------------------------------------
    1519             :  *                      class TABPolyline
    1520             :  *
    1521             :  * Feature class to handle the various MapInfo line types:
    1522             :  *
    1523             :  *     TAB_GEOM_LINE_C         0x04
    1524             :  *     TAB_GEOM_LINE           0x05
    1525             :  *     TAB_GEOM_PLINE_C        0x07
    1526             :  *     TAB_GEOM_PLINE          0x08
    1527             :  *     TAB_GEOM_MULTIPLINE_C   0x25
    1528             :  *     TAB_GEOM_MULTIPLINE     0x26
    1529             :  *     TAB_GEOM_V450_MULTIPLINE_C 0x31
    1530             :  *     TAB_GEOM_V450_MULTIPLINE   0x32
    1531             :  *
    1532             :  * Feature geometry can be either a OGRLineString or a OGRMultiLineString
    1533             :  *--------------------------------------------------------------------*/
    1534             : class TABPolyline final : public TABFeature, public ITABFeaturePen
    1535             : {
    1536             :   private:
    1537             :     GBool m_bCenterIsSet;
    1538             :     double m_dCenterX;
    1539             :     double m_dCenterY;
    1540             :     GBool m_bWriteTwoPointLineAsPolyline;
    1541             : 
    1542             :   public:
    1543             :     explicit TABPolyline(const OGRFeatureDefn *poDefnIn);
    1544             :     ~TABPolyline() override;
    1545             : 
    1546        2311 :     TABFeatureClass GetFeatureClass() override
    1547             :     {
    1548        2311 :         return TABFCPolyline;
    1549             :     }
    1550             : 
    1551             :     virtual TABGeomType
    1552             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    1553             : 
    1554             :     virtual TABFeature *
    1555             :     CloneTABFeature(const OGRFeatureDefn *poNewDefn = nullptr) override;
    1556             : 
    1557             :     /* 2 methods to simplify access to rings in a multiple polyline
    1558             :      */
    1559             :     int GetNumParts();
    1560             :     OGRLineString *GetPartRef(int nPartIndex);
    1561             : 
    1562             :     GBool TwoPointLineAsPolyline();
    1563             :     void TwoPointLineAsPolyline(GBool bTwoPointLineAsPolyline);
    1564             : 
    1565             :     virtual int ReadGeometryFromMAPFile(
    1566             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1567             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1568             :     virtual int
    1569             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1570             :                            GBool bCoordDataOnly = FALSE,
    1571             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1572             : 
    1573             :     int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1574             :     int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1575             : 
    1576             :     const char *GetStyleString() const override;
    1577             : 
    1578             :     void DumpMIF(FILE *fpOut = nullptr) override;
    1579             : 
    1580             :     int GetCenter(double &dX, double &dY);
    1581             :     void SetCenter(double dX, double dY);
    1582             : 
    1583             :     // MapInfo-specific attributes... made available through public vars
    1584             :     // for now.
    1585             :     GBool m_bSmooth;
    1586             : };
    1587             : 
    1588             : /*---------------------------------------------------------------------
    1589             :  *                      class TABRegion
    1590             :  *
    1591             :  * Feature class to handle the MapInfo region types:
    1592             :  *
    1593             :  *     TAB_GEOM_REGION_C         0x0d
    1594             :  *     TAB_GEOM_REGION           0x0e
    1595             :  *     TAB_GEOM_V450_REGION_C    0x2e
    1596             :  *     TAB_GEOM_V450_REGION      0x2f
    1597             :  *
    1598             :  * Feature geometry will be returned as OGRPolygon (with a single ring)
    1599             :  * or OGRMultiPolygon (for multiple rings).
    1600             :  *
    1601             :  * REGIONs with multiple rings are returned as OGRMultiPolygon instead of
    1602             :  * as OGRPolygons since OGRPolygons require that the first ring be the
    1603             :  * outer ring, and the other all be inner rings, but this is not guaranteed
    1604             :  * inside MapInfo files.  However, when writing features, OGRPolygons with
    1605             :  * multiple rings will be accepted without problem.
    1606             :  *--------------------------------------------------------------------*/
    1607             : class TABRegion final : public TABFeature,
    1608             :                         public ITABFeaturePen,
    1609             :                         public ITABFeatureBrush
    1610             : {
    1611             :   private:
    1612             :     GBool m_bSmooth;
    1613             :     GBool m_bCenterIsSet;
    1614             :     double m_dCenterX;
    1615             :     double m_dCenterY;
    1616             : 
    1617             :     int ComputeNumRings(TABMAPCoordSecHdr **ppasSecHdrs, TABMAPFile *poMAPFile);
    1618             :     static int AppendSecHdrs(OGRPolygon *poPolygon,
    1619             :                              TABMAPCoordSecHdr *&pasSecHdrs,
    1620             :                              TABMAPFile *poMAPFile, int &iLastRing);
    1621             : 
    1622             :   public:
    1623             :     explicit TABRegion(const OGRFeatureDefn *poDefnIn);
    1624             :     ~TABRegion() override;
    1625             : 
    1626         438 :     TABFeatureClass GetFeatureClass() override
    1627             :     {
    1628         438 :         return TABFCRegion;
    1629             :     }
    1630             : 
    1631             :     virtual TABGeomType
    1632             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    1633             : 
    1634             :     virtual TABFeature *
    1635             :     CloneTABFeature(const OGRFeatureDefn *poNewDefn = nullptr) override;
    1636             : 
    1637             :     /* 2 methods to make the REGION's geometry look like a single collection
    1638             :      * of OGRLinearRings
    1639             :      */
    1640             :     int GetNumRings();
    1641             :     OGRLinearRing *GetRingRef(int nRequestedRingIndex);
    1642             :     GBool IsInteriorRing(int nRequestedRingIndex);
    1643             : 
    1644             :     virtual int ReadGeometryFromMAPFile(
    1645             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1646             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1647             :     virtual int
    1648             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1649             :                            GBool bCoordDataOnly = FALSE,
    1650             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1651             : 
    1652             :     int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1653             :     int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1654             : 
    1655             :     const char *GetStyleString() const override;
    1656             : 
    1657             :     void DumpMIF(FILE *fpOut = nullptr) override;
    1658             : 
    1659             :     int GetCenter(double &dX, double &dY);
    1660             :     void SetCenter(double dX, double dY);
    1661             : };
    1662             : 
    1663             : /*---------------------------------------------------------------------
    1664             :  *                      class TABRectangle
    1665             :  *
    1666             :  * Feature class to handle the MapInfo rectangle types:
    1667             :  *
    1668             :  *     TAB_GEOM_RECT_C         0x13
    1669             :  *     TAB_GEOM_RECT           0x14
    1670             :  *     TAB_GEOM_ROUNDRECT_C    0x16
    1671             :  *     TAB_GEOM_ROUNDRECT      0x17
    1672             :  *
    1673             :  * A rectangle is defined by the coords of its 2 opposite corners (the MBR)
    1674             :  * Its corners can optionally be rounded, in which case a X and Y rounding
    1675             :  * radius will be defined.
    1676             :  *
    1677             :  * Feature geometry will be OGRPolygon
    1678             :  *--------------------------------------------------------------------*/
    1679             : class TABRectangle final : public TABFeature,
    1680             :                            public ITABFeaturePen,
    1681             :                            public ITABFeatureBrush
    1682             : {
    1683             :   private:
    1684             :     int UpdateMBR(TABMAPFile *poMapFile = nullptr) override;
    1685             : 
    1686             :   public:
    1687             :     explicit TABRectangle(const OGRFeatureDefn *poDefnIn);
    1688             :     ~TABRectangle() override;
    1689             : 
    1690         921 :     TABFeatureClass GetFeatureClass() override
    1691             :     {
    1692         921 :         return TABFCRectangle;
    1693             :     }
    1694             : 
    1695             :     virtual TABGeomType
    1696             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    1697             : 
    1698             :     virtual TABFeature *
    1699             :     CloneTABFeature(const OGRFeatureDefn *poNewDefn = nullptr) override;
    1700             : 
    1701             :     virtual int ReadGeometryFromMAPFile(
    1702             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1703             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1704             :     virtual int
    1705             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1706             :                            GBool bCoordDataOnly = FALSE,
    1707             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1708             : 
    1709             :     int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1710             :     int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1711             : 
    1712             :     const char *GetStyleString() const override;
    1713             : 
    1714             :     void DumpMIF(FILE *fpOut = nullptr) override;
    1715             : 
    1716             :     // MapInfo-specific attributes... made available through public vars
    1717             :     // for now.
    1718             :     GBool m_bRoundCorners;
    1719             :     double m_dRoundXRadius;
    1720             :     double m_dRoundYRadius;
    1721             : };
    1722             : 
    1723             : /*---------------------------------------------------------------------
    1724             :  *                      class TABEllipse
    1725             :  *
    1726             :  * Feature class to handle the MapInfo ellipse types:
    1727             :  *
    1728             :  *     TAB_GEOM_ELLIPSE_C      0x19
    1729             :  *     TAB_GEOM_ELLIPSE        0x1a
    1730             :  *
    1731             :  * An ellipse is defined by the coords of its 2 opposite corners (the MBR)
    1732             :  *
    1733             :  * Feature geometry can be either an OGRPoint defining the center of the
    1734             :  * ellipse, or an OGRPolygon defining the ellipse itself.
    1735             :  *
    1736             :  * When an ellipse is read, the returned geometry is a OGRPolygon representing
    1737             :  * the ellipse with 2 degrees line segments.
    1738             :  *
    1739             :  * In the case of the OGRPoint, then the X/Y Radius MUST be set, but.
    1740             :  * However with an OGRPolygon, if the X/Y radius are not set (== 0) then
    1741             :  * the MBR of the polygon will be used to define the ellipse parameters
    1742             :  * and the center of the MBR is used as the center of the ellipse...
    1743             :  * (i.e. the polygon vertices themselves will be ignored).
    1744             :  *--------------------------------------------------------------------*/
    1745             : class TABEllipse final : public TABFeature,
    1746             :                          public ITABFeaturePen,
    1747             :                          public ITABFeatureBrush
    1748             : {
    1749             :   private:
    1750             :     int UpdateMBR(TABMAPFile *poMapFile = nullptr) override;
    1751             : 
    1752             :   public:
    1753             :     explicit TABEllipse(const OGRFeatureDefn *poDefnIn);
    1754             :     ~TABEllipse() override;
    1755             : 
    1756         387 :     TABFeatureClass GetFeatureClass() override
    1757             :     {
    1758         387 :         return TABFCEllipse;
    1759             :     }
    1760             : 
    1761             :     virtual TABGeomType
    1762             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    1763             : 
    1764             :     virtual TABFeature *
    1765             :     CloneTABFeature(const OGRFeatureDefn *poNewDefn = nullptr) override;
    1766             : 
    1767             :     virtual int ReadGeometryFromMAPFile(
    1768             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1769             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1770             :     virtual int
    1771             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1772             :                            GBool bCoordDataOnly = FALSE,
    1773             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1774             : 
    1775             :     int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1776             :     int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1777             : 
    1778             :     const char *GetStyleString() const override;
    1779             : 
    1780             :     void DumpMIF(FILE *fpOut = nullptr) override;
    1781             : 
    1782             :     // MapInfo-specific attributes... made available through public vars
    1783             :     // for now.
    1784             :     double m_dCenterX;
    1785             :     double m_dCenterY;
    1786             :     double m_dXRadius;
    1787             :     double m_dYRadius;
    1788             : };
    1789             : 
    1790             : /*---------------------------------------------------------------------
    1791             :  *                      class TABArc
    1792             :  *
    1793             :  * Feature class to handle the MapInfo arc types:
    1794             :  *
    1795             :  *     TAB_GEOM_ARC_C      0x0a
    1796             :  *     TAB_GEOM_ARC        0x0b
    1797             :  *
    1798             :  * In MapInfo, an arc is defined by the coords of the MBR corners of its
    1799             :  * defining ellipse, which in this case is different from the arc's MBR,
    1800             :  * and a start and end angle in degrees.
    1801             :  *
    1802             :  * Feature geometry can be either an OGRLineString or an OGRPoint.
    1803             :  *
    1804             :  * In any case, X/Y radius X/Y center, and start/end angle (in degrees
    1805             :  * counterclockwise) MUST be set.
    1806             :  *
    1807             :  * When an arc is read, the returned geometry is an OGRLineString
    1808             :  * representing the arc with 2 degrees line segments.
    1809             :  *--------------------------------------------------------------------*/
    1810             : class TABArc final : public TABFeature, public ITABFeaturePen
    1811             : {
    1812             :   private:
    1813             :     double m_dStartAngle;  // In degrees, counterclockwise,
    1814             :     double m_dEndAngle;    // starting at 3 o'clock
    1815             : 
    1816             :     int UpdateMBR(TABMAPFile *poMapFile = nullptr) override;
    1817             : 
    1818             :   public:
    1819             :     explicit TABArc(const OGRFeatureDefn *poDefnIn);
    1820             :     ~TABArc() override;
    1821             : 
    1822         642 :     TABFeatureClass GetFeatureClass() override
    1823             :     {
    1824         642 :         return TABFCArc;
    1825             :     }
    1826             : 
    1827             :     virtual TABGeomType
    1828             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    1829             : 
    1830             :     virtual TABFeature *
    1831             :     CloneTABFeature(const OGRFeatureDefn *poNewDefn = nullptr) override;
    1832             : 
    1833             :     virtual int ReadGeometryFromMAPFile(
    1834             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1835             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1836             :     virtual int
    1837             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1838             :                            GBool bCoordDataOnly = FALSE,
    1839             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1840             : 
    1841             :     int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1842             :     int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1843             : 
    1844             :     const char *GetStyleString() const override;
    1845             : 
    1846             :     void DumpMIF(FILE *fpOut = nullptr) override;
    1847             : 
    1848           0 :     double GetStartAngle()
    1849             :     {
    1850           0 :         return m_dStartAngle;
    1851             :     }
    1852             : 
    1853           0 :     double GetEndAngle()
    1854             :     {
    1855           0 :         return m_dEndAngle;
    1856             :     }
    1857             : 
    1858             :     void SetStartAngle(double dAngle);
    1859             :     void SetEndAngle(double dAngle);
    1860             : 
    1861             :     // MapInfo-specific attributes... made available through public vars
    1862             :     // for now.
    1863             :     double m_dCenterX;
    1864             :     double m_dCenterY;
    1865             :     double m_dXRadius;
    1866             :     double m_dYRadius;
    1867             : };
    1868             : 
    1869             : /*---------------------------------------------------------------------
    1870             :  *                      class TABText
    1871             :  *
    1872             :  * Feature class to handle the MapInfo text types:
    1873             :  *
    1874             :  *     TAB_GEOM_TEXT_C         0x10
    1875             :  *     TAB_GEOM_TEXT           0x11
    1876             :  *
    1877             :  * Feature geometry is an OGRPoint corresponding to the lower-left
    1878             :  * corner of the text MBR BEFORE ROTATION.
    1879             :  *
    1880             :  * Text string, and box height/width (box before rotation is applied)
    1881             :  * are required in a valid text feature and MUST be set.
    1882             :  * Text angle and other styles are optional.
    1883             :  *--------------------------------------------------------------------*/
    1884             : class TABText final : public TABFeature,
    1885             :                       public ITABFeatureFont,
    1886             :                       public ITABFeaturePen
    1887             : {
    1888             :     CPL_DISALLOW_COPY_ASSIGN(TABText)
    1889             : 
    1890             :   protected:
    1891             :     char *m_pszString;
    1892             : 
    1893             :     double m_dAngle;
    1894             :     double m_dHeight;
    1895             :     mutable double m_dWidth;
    1896             :     double m_dfLineEndX;
    1897             :     double m_dfLineEndY;
    1898             :     GBool m_bLineEndSet;
    1899             :     void UpdateTextMBR();
    1900             : 
    1901             :     GInt32 m_rgbForeground;
    1902             :     GInt32 m_rgbBackground;
    1903             :     GInt32 m_rgbOutline;
    1904             :     GInt32 m_rgbShadow;
    1905             : 
    1906             :     GInt16 m_nTextAlignment;  // Justification/Vert.Spacing/arrow
    1907             :     GInt16 m_nFontStyle;      // Bold/italic/underlined/shadow/...
    1908             : 
    1909             :     const char *GetLabelStyleString() const;
    1910             : 
    1911             :     int UpdateMBR(TABMAPFile *poMapFile = nullptr) override;
    1912             : 
    1913             :   public:
    1914             :     explicit TABText(const OGRFeatureDefn *poDefnIn);
    1915             :     ~TABText() override;
    1916             : 
    1917         280 :     TABFeatureClass GetFeatureClass() override
    1918             :     {
    1919         280 :         return TABFCText;
    1920             :     }
    1921             : 
    1922             :     virtual TABGeomType
    1923             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    1924             : 
    1925             :     virtual TABFeature *
    1926             :     CloneTABFeature(const OGRFeatureDefn *poNewDefn = nullptr) override;
    1927             : 
    1928             :     virtual int ReadGeometryFromMAPFile(
    1929             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1930             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1931             :     virtual int
    1932             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1933             :                            GBool bCoordDataOnly = FALSE,
    1934             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1935             : 
    1936             :     int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1937             :     int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1938             : 
    1939             :     const char *GetStyleString() const override;
    1940             : 
    1941             :     void DumpMIF(FILE *fpOut = nullptr) override;
    1942             : 
    1943             :     void SetLabelFromStyleString(const char *pszStyleString);
    1944             : 
    1945             :     const char *GetTextString() const;
    1946             :     double GetTextAngle() const;
    1947             :     double GetTextBoxHeight() const;
    1948             :     double GetTextBoxWidth() const;
    1949             :     GInt32 GetFontFGColor() const;
    1950             :     GInt32 GetFontBGColor() const;
    1951             :     GInt32 GetFontOColor() const;
    1952             :     GInt32 GetFontSColor() const;
    1953             :     void GetTextLineEndPoint(double &dX, double &dY);
    1954             : 
    1955             :     TABTextJust GetTextJustification() const;
    1956             :     TABTextSpacing GetTextSpacing() const;
    1957             :     TABTextLineType GetTextLineType() const;
    1958             :     GBool QueryFontStyle(TABFontStyle eStyleToQuery) const;
    1959             : 
    1960             :     void SetTextString(const char *pszStr);
    1961             :     void SetTextAngle(double dAngle);
    1962             :     void SetTextBoxHeight(double dHeight);
    1963             :     void SetTextBoxWidth(double dWidth);
    1964             :     void SetFontFGColor(GInt32 rgbColor);
    1965             :     void SetFontBGColor(GInt32 rgbColor);
    1966             :     void SetFontOColor(GInt32 rgbColor);
    1967             :     void SetFontSColor(GInt32 rgbColor);
    1968             :     void SetTextLineEndPoint(double dX, double dY);
    1969             : 
    1970             :     void SetTextJustification(TABTextJust eJust);
    1971             :     void SetTextSpacing(TABTextSpacing eSpacing);
    1972             :     void SetTextLineType(TABTextLineType eLineType);
    1973             :     void ToggleFontStyle(TABFontStyle eStyleToToggle, GBool bStatus);
    1974             : 
    1975             :     int GetFontStyleMIFValue() const;
    1976             :     void SetFontStyleMIFValue(int nStyle, GBool bBGColorSet = FALSE);
    1977             :     GBool IsFontBGColorUsed() const;
    1978             :     GBool IsFontOColorUsed() const;
    1979             :     GBool IsFontSColorUsed() const;
    1980             :     GBool IsFontBold() const;
    1981             :     GBool IsFontItalic() const;
    1982             :     GBool IsFontUnderline() const;
    1983             : 
    1984           0 :     int GetFontStyleTABValue() const
    1985             :     {
    1986           0 :         return m_nFontStyle;
    1987             :     }
    1988             : 
    1989           0 :     void SetFontStyleTABValue(int nStyle)
    1990             :     {
    1991           0 :         m_nFontStyle = static_cast<GInt16>(nStyle);
    1992           0 :     }
    1993             : };
    1994             : 
    1995             : /*---------------------------------------------------------------------
    1996             :  *                      class TABMultiPoint
    1997             :  *
    1998             :  * Feature class to handle MapInfo Multipoint features:
    1999             :  *
    2000             :  *     TAB_GEOM_MULTIPOINT_C        0x34
    2001             :  *     TAB_GEOM_MULTIPOINT          0x35
    2002             :  *
    2003             :  * Feature geometry will be a OGRMultiPoint
    2004             :  *
    2005             :  * The symbol number is in the range [31..67], with 31=None and corresponds
    2006             :  * to one of the 35 predefined "Old MapInfo Symbols"
    2007             :  *--------------------------------------------------------------------*/
    2008             : class TABMultiPoint final : public TABFeature, public ITABFeatureSymbol
    2009             : {
    2010             :   private:
    2011             :     // We call it center, but it is more like a label point
    2012             :     // Its value default to be the location of the first point
    2013             :     GBool m_bCenterIsSet;
    2014             :     double m_dCenterX;
    2015             :     double m_dCenterY;
    2016             : 
    2017             :   public:
    2018             :     explicit TABMultiPoint(const OGRFeatureDefn *poDefnIn);
    2019             :     ~TABMultiPoint() override;
    2020             : 
    2021         149 :     TABFeatureClass GetFeatureClass() override
    2022             :     {
    2023         149 :         return TABFCMultiPoint;
    2024             :     }
    2025             : 
    2026             :     virtual TABGeomType
    2027             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    2028             : 
    2029             :     virtual TABFeature *
    2030             :     CloneTABFeature(const OGRFeatureDefn *poNewDefn = nullptr) override;
    2031             : 
    2032             :     int GetXY(int i, double &dX, double &dY);
    2033             :     int GetNumPoints();
    2034             : 
    2035             :     int GetCenter(double &dX, double &dY);
    2036             :     void SetCenter(double dX, double dY);
    2037             : 
    2038             :     virtual int ReadGeometryFromMAPFile(
    2039             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    2040             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    2041             :     virtual int
    2042             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    2043             :                            GBool bCoordDataOnly = FALSE,
    2044             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    2045             : 
    2046             :     int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    2047             :     int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    2048             : 
    2049             :     const char *GetStyleString() const override;
    2050             : 
    2051             :     void DumpMIF(FILE *fpOut = nullptr) override;
    2052             : };
    2053             : 
    2054             : /*---------------------------------------------------------------------
    2055             :  *
    2056             :  *                      class TABCollection
    2057             :  *
    2058             :  * Feature class to handle MapInfo Collection features:
    2059             :  *
    2060             :  *     TAB_GEOM_COLLECTION_C        0x37
    2061             :  *     TAB_GEOM_COLLECTION          0x38
    2062             :  *
    2063             :  * Feature geometry will be a OGRCollection
    2064             :  *
    2065             :  * **** IMPORTANT NOTE: ****
    2066             :  *
    2067             :  * The current implementation does not allow setting the Geometry via
    2068             :  * OGRFeature::SetGeometry*(). The geometries must be set via the
    2069             :  * TABCollection::SetRegion/Pline/MpointDirectly() methods which will take
    2070             :  * care of keeping the OGRFeature's geometry in sync.
    2071             :  *
    2072             :  * If we ever want to support creating collections via the OGR interface then
    2073             :  * something should be added in TABCollection::WriteGeometryToMapFile(), or
    2074             :  * perhaps in ValidateMapInfoType(), or even better in a custom
    2075             :  * TABCollection::SetGeometry*()... but then this last option may not work
    2076             :  * unless OGRFeature::SetGeometry*() are made virtual in OGR.
    2077             :  *
    2078             :  *--------------------------------------------------------------------*/
    2079             : class TABCollection final : public TABFeature, public ITABFeatureSymbol
    2080             : {
    2081             :     CPL_DISALLOW_COPY_ASSIGN(TABCollection)
    2082             : 
    2083             :   private:
    2084             :     TABRegion *m_poRegion;
    2085             :     TABPolyline *m_poPline;
    2086             :     TABMultiPoint *m_poMpoint;
    2087             : 
    2088             :     void EmptyCollection();
    2089             :     static int ReadLabelAndMBR(TABMAPCoordBlock *poCoordBlock,
    2090             :                                GBool bComprCoord, GInt32 nComprOrgX,
    2091             :                                GInt32 nComprOrgY, GInt32 &pnMinX,
    2092             :                                GInt32 &pnMinY, GInt32 &pnMaxX, GInt32 &pnMaxY,
    2093             :                                GInt32 &pnLabelX, GInt32 &pnLabelY);
    2094             :     static int WriteLabelAndMBR(TABMAPCoordBlock *poCoordBlock,
    2095             :                                 GBool bComprCoord, GInt32 nMinX, GInt32 nMinY,
    2096             :                                 GInt32 nMaxX, GInt32 nMaxY, GInt32 nLabelX,
    2097             :                                 GInt32 nLabelY);
    2098             :     int SyncOGRGeometryCollection(GBool bSyncRegion, GBool bSyncPline,
    2099             :                                   GBool bSyncMpoint);
    2100             : 
    2101             :   public:
    2102             :     explicit TABCollection(const OGRFeatureDefn *poDefnIn);
    2103             :     ~TABCollection() override;
    2104             : 
    2105           2 :     TABFeatureClass GetFeatureClass() override
    2106             :     {
    2107           2 :         return TABFCCollection;
    2108             :     }
    2109             : 
    2110             :     virtual TABGeomType
    2111             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    2112             : 
    2113             :     virtual TABFeature *
    2114             :     CloneTABFeature(const OGRFeatureDefn *poNewDefn = nullptr) override;
    2115             : 
    2116             :     virtual int ReadGeometryFromMAPFile(
    2117             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    2118             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    2119             :     virtual int
    2120             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    2121             :                            GBool bCoordDataOnly = FALSE,
    2122             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    2123             : 
    2124             :     int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    2125             :     int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    2126             : 
    2127             :     const char *GetStyleString() const override;
    2128             : 
    2129             :     void DumpMIF(FILE *fpOut = nullptr) override;
    2130             : 
    2131             :     TABRegion *GetRegionRef()
    2132             :     {
    2133             :         return m_poRegion;
    2134             :     }
    2135             : 
    2136             :     TABPolyline *GetPolylineRef()
    2137             :     {
    2138             :         return m_poPline;
    2139             :     }
    2140             : 
    2141             :     TABMultiPoint *GetMultiPointRef()
    2142             :     {
    2143             :         return m_poMpoint;
    2144             :     }
    2145             : 
    2146             :     int SetRegionDirectly(TABRegion *poRegion);
    2147             :     int SetPolylineDirectly(TABPolyline *poPline);
    2148             :     int SetMultiPointDirectly(TABMultiPoint *poMpoint);
    2149             : };
    2150             : 
    2151             : /*---------------------------------------------------------------------
    2152             :  *                      class TABDebugFeature
    2153             :  *
    2154             :  * Feature class to use for testing purposes... this one does not
    2155             :  * correspond to any MapInfo type... it is just used to dump info about
    2156             :  * feature types that are not implemented yet.
    2157             :  *--------------------------------------------------------------------*/
    2158             : class TABDebugFeature final : public TABFeature
    2159             : {
    2160             :   private:
    2161             :     GByte m_abyBuf[512];
    2162             :     int m_nSize;
    2163             :     int m_nCoordDataPtr;  // -1 if none
    2164             :     int m_nCoordDataSize;
    2165             : 
    2166             :   public:
    2167             :     explicit TABDebugFeature(const OGRFeatureDefn *poDefnIn);
    2168             :     ~TABDebugFeature() override;
    2169             : 
    2170           0 :     TABFeatureClass GetFeatureClass() override
    2171             :     {
    2172           0 :         return TABFCDebugFeature;
    2173             :     }
    2174             : 
    2175             :     virtual int ReadGeometryFromMAPFile(
    2176             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    2177             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    2178             :     virtual int
    2179             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    2180             :                            GBool bCoordDataOnly = FALSE,
    2181             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    2182             : 
    2183             :     int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    2184             :     int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    2185             : 
    2186             :     void DumpMIF(FILE *fpOut = nullptr) override;
    2187             : };
    2188             : 
    2189             : #endif /* MITAB_H_INCLUDED_ */

Generated by: LCOV version 1.14