LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/mitab - mitab.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 115 220 52.3 %
Date: 2024-11-21 22:18:42 Functions: 49 100 49.0 %

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

Generated by: LCOV version 1.14