LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/openfilegdb - filegdbtable.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 127 129 98.4 %
Date: 2024-05-02 22:57:13 Functions: 61 64 95.3 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * $Id$
       3             :  *
       4             :  * Project:  OpenGIS Simple Features Reference Implementation
       5             :  * Purpose:  Implements reading of FileGDB tables
       6             :  * Author:   Even Rouault, <even dot rouault at spatialys.com>
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2014, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * Permission is hereby granted, free of charge, to any person obtaining a
      12             :  * copy of this software and associated documentation files (the "Software"),
      13             :  * to deal in the Software without restriction, including without limitation
      14             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15             :  * and/or sell copies of the Software, and to permit persons to whom the
      16             :  * Software is furnished to do so, subject to the following conditions:
      17             :  *
      18             :  * The above copyright notice and this permission notice shall be included
      19             :  * in all copies or substantial portions of the Software.
      20             :  *
      21             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27             :  * DEALINGS IN THE SOFTWARE.
      28             :  ****************************************************************************/
      29             : 
      30             : #ifndef FILEGDBTABLE_H_INCLUDED
      31             : #define FILEGDBTABLE_H_INCLUDED
      32             : 
      33             : #include "ogr_core.h"
      34             : #include "cpl_vsi.h"
      35             : #include "ogr_geometry.h"
      36             : 
      37             : #include <limits>
      38             : #include <string>
      39             : #include <vector>
      40             : 
      41             : namespace OpenFileGDB
      42             : {
      43             : constexpr uint64_t OFFSET_MINUS_ONE = static_cast<uint64_t>(-1);
      44             : constexpr int MAX_CAR_COUNT_INDEXED_STR = 80;
      45             : 
      46             : /************************************************************************/
      47             : /*                        FileGDBTableGeometryType                      */
      48             : /************************************************************************/
      49             : 
      50             : /* FGTGT = (F)ile(G)DB(T)able(G)eometry(T)ype */
      51             : typedef enum
      52             : {
      53             :     FGTGT_NONE = 0,
      54             :     FGTGT_POINT = 1,
      55             :     FGTGT_MULTIPOINT = 2,
      56             :     FGTGT_LINE = 3,
      57             :     FGTGT_POLYGON = 4,
      58             :     FGTGT_MULTIPATCH = 9
      59             : } FileGDBTableGeometryType;
      60             : 
      61             : /************************************************************************/
      62             : /*                          FileGDBFieldType                            */
      63             : /************************************************************************/
      64             : 
      65             : /* FGFT = (F)ile(G)DB(F)ield(T)ype */
      66             : typedef enum
      67             : {
      68             :     FGFT_UNDEFINED = -1,
      69             :     FGFT_INT16 = 0,
      70             :     FGFT_INT32 = 1,
      71             :     FGFT_FLOAT32 = 2,
      72             :     FGFT_FLOAT64 = 3,
      73             :     FGFT_STRING = 4,
      74             :     FGFT_DATETIME = 5,
      75             :     FGFT_OBJECTID = 6,
      76             :     FGFT_GEOMETRY = 7,
      77             :     FGFT_BINARY = 8,
      78             :     FGFT_RASTER = 9,
      79             :     FGFT_GUID = 10,
      80             :     FGFT_GLOBALID = 11,
      81             :     FGFT_XML = 12,
      82             :     FGFT_INT64 = 13,                 // added in ArcGIS Pro 3.2
      83             :     FGFT_DATE = 14,                  // added in ArcGIS Pro 3.2
      84             :     FGFT_TIME = 15,                  // added in ArcGIS Pro 3.2
      85             :     FGFT_DATETIME_WITH_OFFSET = 16,  // added in ArcGIS Pro 3.2
      86             : } FileGDBFieldType;
      87             : 
      88             : /************************************************************************/
      89             : /*                          FileGDBField                                */
      90             : /************************************************************************/
      91             : 
      92             : class FileGDBTable;
      93             : class FileGDBIndex;
      94             : 
      95             : class FileGDBField
      96             : {
      97             :     friend class FileGDBTable;
      98             : 
      99             :     FileGDBTable *m_poParent = nullptr;
     100             : 
     101             :     std::string m_osName{};
     102             :     std::string m_osAlias{};
     103             :     FileGDBFieldType m_eType = FGFT_UNDEFINED;
     104             : 
     105             :     bool m_bNullable = false;
     106             :     bool m_bHighPrecsion = false;  // for FGFT_DATETIME
     107             :     bool m_bReadAsDouble =
     108             :         false;           // used by FileGDBTable::CreateAttributeIndex()
     109             :     int m_nMaxWidth = 0; /* for string */
     110             : 
     111             :     OGRField m_sDefault{};
     112             : 
     113             :     FileGDBIndex *m_poIndex = nullptr;
     114             : 
     115             :     FileGDBField(const FileGDBField &) = delete;
     116             :     FileGDBField &operator=(const FileGDBField &) = delete;
     117             : 
     118             :   public:
     119             :     static const OGRField UNSET_FIELD;
     120             : 
     121             :     explicit FileGDBField(FileGDBTable *m_poParent);
     122             :     FileGDBField(const std::string &osName, const std::string &osAlias,
     123             :                  FileGDBFieldType eType, bool bNullable, int nMaxWidth,
     124             :                  const OGRField &sDefault);
     125             :     virtual ~FileGDBField();
     126             : 
     127       12935 :     void SetParent(FileGDBTable *poParent)
     128             :     {
     129       12935 :         m_poParent = poParent;
     130       12935 :     }
     131             : 
     132      248770 :     const std::string &GetName() const
     133             :     {
     134      248770 :         return m_osName;
     135             :     }
     136             : 
     137       18868 :     const std::string &GetAlias() const
     138             :     {
     139       18868 :         return m_osAlias;
     140             :     }
     141             : 
     142      331481 :     FileGDBFieldType GetType() const
     143             :     {
     144      331481 :         return m_eType;
     145             :     }
     146             : 
     147      133563 :     bool IsNullable() const
     148             :     {
     149      133563 :         return m_bNullable;
     150             :     }
     151             : 
     152        8431 :     int GetMaxWidth() const
     153             :     {
     154        8431 :         return m_nMaxWidth;
     155             :     }
     156             : 
     157       19110 :     const OGRField *GetDefault() const
     158             :     {
     159       19110 :         return &m_sDefault;
     160             :     }
     161             : 
     162           2 :     void SetHighPrecision()
     163             :     {
     164           2 :         m_bHighPrecsion = true;
     165           2 :     }
     166             : 
     167        8626 :     bool IsHighPrecision() const
     168             :     {
     169        8626 :         return m_bHighPrecsion;
     170             :     }
     171             : 
     172             :     int HasIndex();
     173             :     FileGDBIndex *GetIndex();
     174             : };
     175             : 
     176             : /************************************************************************/
     177             : /*                         FileGDBGeomField                             */
     178             : /************************************************************************/
     179             : 
     180             : class FileGDBGeomField : public FileGDBField
     181             : {
     182             :     friend class FileGDBTable;
     183             : 
     184             :     static const double ESRI_NAN;
     185             : 
     186             :     std::string m_osWKT{};
     187             :     int m_bHasZOriginScaleTolerance = 0;
     188             :     int m_bHasMOriginScaleTolerance = 0;
     189             :     double m_dfXOrigin = 0;
     190             :     double m_dfYOrigin = 0;
     191             :     double m_dfXYScale = 0;
     192             :     double m_dfMOrigin = 0;
     193             :     double m_dfMScale = 0;
     194             :     double m_dfZOrigin = 0;
     195             :     double m_dfZScale = 0;
     196             :     double m_dfXYTolerance = 0;
     197             :     double m_dfMTolerance = 0;
     198             :     double m_dfZTolerance = 0;
     199             :     double m_dfXMin = ESRI_NAN;
     200             :     double m_dfYMin = ESRI_NAN;
     201             :     double m_dfZMin = ESRI_NAN;
     202             :     double m_dfMMin = ESRI_NAN;
     203             :     double m_dfXMax = ESRI_NAN;
     204             :     double m_dfYMax = ESRI_NAN;
     205             :     double m_dfZMax = ESRI_NAN;
     206             :     double m_dfMMax = ESRI_NAN;
     207             :     std::vector<double> m_adfSpatialIndexGridResolution{};
     208             : 
     209             :   public:
     210             :     explicit FileGDBGeomField(FileGDBTable *m_poParent);
     211             :     FileGDBGeomField(const std::string &osName, const std::string &osAlias,
     212             :                      bool bNullable, const std::string &osWKT, double dfXOrigin,
     213             :                      double dfYOrigin, double dfXYScale, double dfXYTolerance,
     214             :                      const std::vector<double> &adfSpatialIndexGridResolution);
     215             : 
     216        4853 :     virtual ~FileGDBGeomField()
     217        2428 :     {
     218        4853 :     }
     219             : 
     220        2261 :     const std::string &GetWKT() const
     221             :     {
     222        2261 :         return m_osWKT;
     223             :     }
     224             : 
     225       12540 :     double GetXMin() const
     226             :     {
     227       12540 :         return m_dfXMin;
     228             :     }
     229             : 
     230        6603 :     double GetYMin() const
     231             :     {
     232        6603 :         return m_dfYMin;
     233             :     }
     234             : 
     235        3838 :     double GetZMin() const
     236             :     {
     237        3838 :         return m_dfZMin;
     238             :     }  // only valid for m_bGeomTypeHasZ
     239             : 
     240          24 :     double GetMMin() const
     241             :     {
     242          24 :         return m_dfMMin;
     243             :     }  // only valid for m_bGeomTypeHasM
     244             : 
     245        6603 :     double GetXMax() const
     246             :     {
     247        6603 :         return m_dfXMax;
     248             :     }
     249             : 
     250        6603 :     double GetYMax() const
     251             :     {
     252        6603 :         return m_dfYMax;
     253             :     }
     254             : 
     255        3832 :     double GetZMax() const
     256             :     {
     257        3832 :         return m_dfZMax;
     258             :     }  // only valid for m_bGeomTypeHasZ
     259             : 
     260          24 :     double GetMMax() const
     261             :     {
     262          24 :         return m_dfMMax;
     263             :     }  // only valid for m_bGeomTypeHasM
     264             : 
     265             :     void SetXYMinMax(double dfXMin, double dfYMin, double dfXMax,
     266             :                      double dfYMax);
     267             :     void SetZMinMax(double dfZMin, double dfZMax);
     268             :     void SetMMinMax(double dfMMin, double dfMMax);
     269             : 
     270        1617 :     int HasZOriginScaleTolerance() const
     271             :     {
     272        1617 :         return m_bHasZOriginScaleTolerance;
     273             :     }
     274             : 
     275        1617 :     int HasMOriginScaleTolerance() const
     276             :     {
     277        1617 :         return m_bHasMOriginScaleTolerance;
     278             :     }
     279             : 
     280       53431 :     double GetXOrigin() const
     281             :     {
     282       53431 :         return m_dfXOrigin;
     283             :     }
     284             : 
     285       53431 :     double GetYOrigin() const
     286             :     {
     287       53431 :         return m_dfYOrigin;
     288             :     }
     289             : 
     290      105831 :     double GetXYScale() const
     291             :     {
     292      105831 :         return m_dfXYScale;
     293             :     }
     294             : 
     295        1201 :     double GetXYTolerance() const
     296             :     {
     297        1201 :         return m_dfXYTolerance;
     298             :     }
     299             : 
     300       20978 :     double GetZOrigin() const
     301             :     {
     302       20978 :         return m_dfZOrigin;
     303             :     }
     304             : 
     305        4761 :     double GetZScale() const
     306             :     {
     307        4761 :         return m_dfZScale;
     308             :     }
     309             : 
     310        1201 :     double GetZTolerance() const
     311             :     {
     312        1201 :         return m_dfZTolerance;
     313             :     }
     314             : 
     315             :     void SetZOriginScaleTolerance(double dfZOrigin, double dfZScale,
     316             :                                   double dfZTolerance);
     317             : 
     318        2334 :     double GetMOrigin() const
     319             :     {
     320        2334 :         return m_dfMOrigin;
     321             :     }
     322             : 
     323        1630 :     double GetMScale() const
     324             :     {
     325        1630 :         return m_dfMScale;
     326             :     }
     327             : 
     328        1201 :     double GetMTolerance() const
     329             :     {
     330        1201 :         return m_dfMTolerance;
     331             :     }
     332             : 
     333             :     void SetMOriginScaleTolerance(double dfMOrigin, double dfMScale,
     334             :                                   double dfMTolerance);
     335             : 
     336        1051 :     const std::vector<double> &GetSpatialIndexGridResolution() const
     337             :     {
     338        1051 :         return m_adfSpatialIndexGridResolution;
     339             :     }
     340             : };
     341             : 
     342             : /************************************************************************/
     343             : /*                         FileGDBRasterField                           */
     344             : /************************************************************************/
     345             : 
     346             : class FileGDBRasterField : public FileGDBGeomField
     347             : {
     348             :   public:
     349             :     enum class Type
     350             :     {
     351             :         EXTERNAL,
     352             :         MANAGED,
     353             :         INLINE,
     354             :     };
     355             : 
     356             :   private:
     357             :     friend class FileGDBTable;
     358             : 
     359             :     std::string m_osRasterColumnName{};
     360             : 
     361             :     Type m_eRasterType = Type::EXTERNAL;
     362             : 
     363             :     FileGDBRasterField(const FileGDBRasterField &) = delete;
     364             :     FileGDBRasterField &operator=(const FileGDBRasterField &) = delete;
     365             : 
     366             :   public:
     367           3 :     explicit FileGDBRasterField(FileGDBTable *poParentIn)
     368           3 :         : FileGDBGeomField(poParentIn)
     369             :     {
     370           3 :     }
     371             : 
     372           6 :     virtual ~FileGDBRasterField()
     373           3 :     {
     374           6 :     }
     375             : 
     376             :     const std::string &GetRasterColumnName() const
     377             :     {
     378             :         return m_osRasterColumnName;
     379             :     }
     380             : 
     381           1 :     Type GetRasterType() const
     382             :     {
     383           1 :         return m_eRasterType;
     384             :     }
     385             : };
     386             : 
     387             : /************************************************************************/
     388             : /*                           FileGDBIndex                               */
     389             : /************************************************************************/
     390             : 
     391             : class FileGDBIndex
     392             : {
     393             :     friend class FileGDBTable;
     394             :     std::string m_osIndexName{};
     395             :     std::string m_osExpression{};
     396             : 
     397             :   public:
     398        1057 :     FileGDBIndex()
     399        1057 :     {
     400        1057 :     }
     401             : 
     402        2114 :     virtual ~FileGDBIndex()
     403        1057 :     {
     404        2114 :     }
     405             : 
     406        1345 :     const std::string &GetIndexName() const
     407             :     {
     408        1345 :         return m_osIndexName;
     409             :     }
     410             : 
     411         707 :     const std::string &GetExpression() const
     412             :     {
     413         707 :         return m_osExpression;
     414             :     }
     415             : 
     416             :     std::string GetFieldName() const;
     417             :     int GetMaxWidthInBytes(const FileGDBTable *poTable) const;
     418             : 
     419             :     static std::string
     420             :     GetFieldNameFromExpression(const std::string &osExpression);
     421             : };
     422             : 
     423             : /************************************************************************/
     424             : /*                           FileGDBTable                               */
     425             : /************************************************************************/
     426             : 
     427             : class FileGDBTable
     428             : {
     429             :     VSILFILE *m_fpTable = nullptr;
     430             :     VSILFILE *m_fpTableX = nullptr;
     431             :     vsi_l_offset m_nFileSize = 0; /* only read when needed */
     432             :     bool m_bUpdate = false;
     433             : 
     434             :     std::string m_osFilename{};
     435             :     bool m_bIsV9 = false;
     436             :     std::vector<std::unique_ptr<FileGDBField>> m_apoFields{};
     437             :     int m_iObjectIdField = -1;
     438             : 
     439             :     int m_bHasReadGDBIndexes = FALSE;
     440             :     std::vector<std::unique_ptr<FileGDBIndex>> m_apoIndexes{};
     441             : 
     442             :     int m_nHasSpatialIndex = -1;
     443             : 
     444             :     bool m_bDirtyHeader = false;
     445             :     bool m_bDirtyFieldDescriptors = false;
     446             :     bool m_bDirtyIndices = false;
     447             :     bool m_bDirtyGdbIndexesFile = false;
     448             : 
     449             :     uint32_t m_nHeaderBufferMaxSize = 0;
     450             :     GUIntBig m_nOffsetFieldDesc = 0;
     451             :     GUInt32 m_nFieldDescLength = 0;
     452             :     bool m_bDirtyGeomFieldBBox = false;
     453             :     bool m_bDirtyGeomFieldSpatialIndexGridRes = false;
     454             :     uint32_t m_nGeomFieldBBoxSubOffset =
     455             :         0;  // offset of geometry field bounding box
     456             :             // relative to m_nOffsetFieldDesc
     457             :     uint32_t m_nGeomFieldSpatialIndexGridResSubOffset =
     458             :         0;  // offset of geometry field spatial index grid resolution
     459             :             // relative to m_nOffsetFieldDesc
     460             : 
     461             :     GUInt32 m_nTablxOffsetSize =
     462             :         0;  // 4 (4 GB limit), 5 (1 TB limit), 6 (256 TB limit)
     463             :     std::vector<vsi_l_offset>
     464             :         m_anFeatureOffsets{}; /* MSb set marks deleted feature. Only used when
     465             :                                  no .gdbtablx file */
     466             : 
     467             :     uint64_t m_nOffsetTableXTrailer = 0;
     468             :     uint32_t m_n1024BlocksPresent = 0;
     469             :     std::vector<GByte> m_abyTablXBlockMap{};
     470             :     int m_nCountBlocksBeforeIBlockIdx = 0;   /* optimization */
     471             :     int m_nCountBlocksBeforeIBlockValue = 0; /* optimization */
     472             :     bool m_bDirtyTableXHeader = false;
     473             :     bool m_bDirtyTableXTrailer = false;
     474             : 
     475             :     int m_nHasFreeList = -1;
     476             :     bool m_bFreelistCanBeDeleted = false;
     477             : 
     478             :     char m_achGUIDBuffer[32 + 6 + 1]{0};
     479             :     int m_nChSaved = -1;
     480             : 
     481             :     int m_bError = FALSE;
     482             :     int m_nCurRow = -1;
     483             :     int m_bHasDeletedFeaturesListed = FALSE;
     484             :     int m_bIsDeleted = FALSE;
     485             :     int m_nLastCol = -1;
     486             :     GByte *m_pabyIterVals = nullptr;
     487             :     int m_iAccNullable = 0;
     488             :     GUInt32 m_nRowBlobLength = 0;
     489             :     OGRField m_sCurField{};
     490             : 
     491             :     FileGDBTableGeometryType m_eTableGeomType = FGTGT_NONE;
     492             :     bool m_bGeomTypeHasZ = false;
     493             :     bool m_bGeomTypeHasM = false;
     494             :     bool m_bStringsAreUTF8 = true;  // if false, UTF16
     495             :     std::string m_osTempString{};   // used as a temporary to store strings
     496             :                                     // recoded from UTF16 to UTF8
     497             :     int m_nValidRecordCount = 0;
     498             :     int m_nTotalRecordCount = 0;
     499             :     int m_iGeomField = -1;
     500             :     int m_nCountNullableFields = 0;
     501             :     int m_nNullableFieldsSizeInBytes = 0;
     502             : 
     503             :     std::vector<double> m_adfSpatialIndexGridResolution{};
     504             : 
     505             :     GUInt32 m_nRowBufferMaxSize = 0;
     506             :     std::vector<GByte> m_abyBuffer{};
     507             :     std::vector<GByte> m_abyGeomBuffer{};
     508             :     std::vector<GByte> m_abyCurvePart{};
     509             :     std::vector<uint32_t> m_anNumberPointsPerPart{};
     510             :     std::vector<double> m_adfX{};
     511             :     std::vector<double> m_adfY{};
     512             :     std::vector<double> m_adfZ{};
     513             :     std::vector<double> m_adfM{};
     514             : 
     515             :     std::string m_osCacheRasterFieldPath{};
     516             : 
     517             :     GUIntBig m_nFilterXMin = 0, m_nFilterXMax = 0, m_nFilterYMin = 0,
     518             :              m_nFilterYMax = 0;
     519             : 
     520             :     class WholeFileRewriter
     521             :     {
     522             :         FileGDBTable &m_oTable;
     523             :         bool m_bModifyInPlace = false;
     524             :         std::string m_osGdbTablx{};
     525             :         std::string m_osBackupValidFilename{};
     526             :         std::string m_osBackupGdbTable{};
     527             :         std::string m_osBackupGdbTablx{};
     528             :         std::string m_osTmpGdbTable{};
     529             :         std::string m_osTmpGdbTablx{};
     530             :         bool m_bOldDirtyIndices = false;
     531             :         uint64_t m_nOldFileSize = 0;
     532             :         uint64_t m_nOldOffsetFieldDesc = 0;
     533             :         uint32_t m_nOldFieldDescLength = 0;
     534             :         bool m_bIsInit = false;
     535             : 
     536             :         WholeFileRewriter(const WholeFileRewriter &) = delete;
     537             :         WholeFileRewriter &operator=(const WholeFileRewriter &) = delete;
     538             : 
     539             :       public:
     540             :         VSILFILE *m_fpOldGdbtable = nullptr;
     541             :         VSILFILE *m_fpOldGdbtablx = nullptr;
     542             :         VSILFILE *m_fpTable = nullptr;
     543             :         VSILFILE *m_fpTableX = nullptr;
     544             : 
     545          45 :         explicit WholeFileRewriter(FileGDBTable &oTable) : m_oTable(oTable)
     546             :         {
     547          45 :         }
     548             : 
     549             :         ~WholeFileRewriter();
     550             : 
     551             :         bool Begin();
     552             :         bool Commit();
     553             :         void Rollback();
     554             :     };
     555             : 
     556             :     bool WriteHeader(VSILFILE *fpTable);
     557             :     bool WriteHeaderX(VSILFILE *fpTableX);
     558             : 
     559             :     int ReadTableXHeader();
     560             :     int IsLikelyFeatureAtOffset(vsi_l_offset nOffset, GUInt32 *pnSize,
     561             :                                 int *pbDeletedRecord);
     562             :     bool GuessFeatureLocations();
     563             :     bool WriteFieldDescriptors(VSILFILE *fpTable);
     564             :     bool SeekIntoTableXForNewFeature(int nObjectID);
     565             :     uint64_t ReadFeatureOffset(const GByte *pabyBuffer);
     566             :     void WriteFeatureOffset(uint64_t nFeatureOffset, GByte *pabyBuffer);
     567             :     bool WriteFeatureOffset(uint64_t nFeatureOffset);
     568             :     bool EncodeFeature(const std::vector<OGRField> &asRawFields,
     569             :                        const OGRGeometry *poGeom, int iSkipField);
     570             :     bool EncodeGeometry(const FileGDBGeomField *poGeomField,
     571             :                         const OGRGeometry *poGeom);
     572             :     bool RewriteTableToAddLastAddedField();
     573             :     void CreateGdbIndexesFile();
     574             :     void RemoveIndices();
     575             :     void RefreshIndices();
     576             :     bool CreateAttributeIndex(const FileGDBIndex *poIndex);
     577             :     uint64_t GetOffsetOfFreeAreaFromFreeList(uint32_t nSize);
     578             :     void AddEntryToFreelist(uint64_t nOffset, uint32_t nSize);
     579             : 
     580             :     FileGDBTable(const FileGDBTable &) = delete;
     581             :     FileGDBTable &operator=(const FileGDBTable &) = delete;
     582             : 
     583             :   public:
     584             :     FileGDBTable();
     585             :     ~FileGDBTable();
     586             : 
     587             :     bool Open(const char *pszFilename, bool bUpdate,
     588             :               const char *pszLayerName = nullptr);
     589             : 
     590             :     bool Create(const char *pszFilename, int nTablxOffsetSize,
     591             :                 FileGDBTableGeometryType eTableGeomType, bool bGeomTypeHasZ,
     592             :                 bool bGeomTypeHasM);
     593             :     bool SetTextUTF16();
     594             : 
     595             :     bool Sync(VSILFILE *fpTable = nullptr, VSILFILE *fpTableX = nullptr);
     596             :     bool Repack();
     597             :     void RecomputeExtent();
     598             : 
     599             :     //! Object should no longer be used after Close()
     600             :     void Close();
     601             : 
     602         194 :     bool IsFileGDBV9() const
     603             :     {
     604         194 :         return m_bIsV9;
     605             :     }
     606             : 
     607        1667 :     const std::string &GetFilename() const
     608             :     {
     609        1667 :         return m_osFilename;
     610             :     }
     611             : 
     612        4666 :     FileGDBTableGeometryType GetGeometryType() const
     613             :     {
     614        4666 :         return m_eTableGeomType;
     615             :     }
     616             : 
     617         142 :     bool GetGeomTypeHasZ() const
     618             :     {
     619         142 :         return m_bGeomTypeHasZ;
     620             :     }
     621             : 
     622         142 :     bool GetGeomTypeHasM() const
     623             :     {
     624         142 :         return m_bGeomTypeHasM;
     625             :     }
     626             : 
     627        3850 :     int GetValidRecordCount() const
     628             :     {
     629        3850 :         return m_nValidRecordCount;
     630             :     }
     631             : 
     632      113564 :     int GetTotalRecordCount() const
     633             :     {
     634      113564 :         return m_nTotalRecordCount;
     635             :     }
     636             : 
     637      233061 :     int GetFieldCount() const
     638             :     {
     639      233061 :         return static_cast<int>(m_apoFields.size());
     640             :     }
     641             : 
     642       46110 :     FileGDBField *GetField(int i) const
     643             :     {
     644       46110 :         return m_apoFields[i].get();
     645             :     }
     646             : 
     647        1041 :     int GetGeomFieldIdx() const
     648             :     {
     649        1041 :         return m_iGeomField;
     650             :     }
     651             : 
     652        1429 :     const FileGDBGeomField *GetGeomField() const
     653             :     {
     654        2857 :         return (m_iGeomField >= 0) ? cpl::down_cast<FileGDBGeomField *>(
     655        1428 :                                          m_apoFields[m_iGeomField].get())
     656        1429 :                                    : nullptr;
     657             :     }
     658             : 
     659      171592 :     int GetObjectIdFieldIdx() const
     660             :     {
     661      171592 :         return m_iObjectIdField;
     662             :     }
     663             : 
     664             :     int GetFieldIdx(const std::string &osName) const;
     665             : 
     666             :     int GetIndexCount();
     667             : 
     668             :     const FileGDBIndex *GetIndex(int i) const
     669             :     {
     670             :         return m_apoIndexes[i].get();
     671             :     }
     672             : 
     673             :     bool HasSpatialIndex();
     674             :     bool CreateIndex(const std::string &osIndexName,
     675             :                      const std::string &osExpression);
     676             :     void ComputeOptimalSpatialIndexGridResolution();
     677             :     bool CreateSpatialIndex();
     678             : 
     679             :     vsi_l_offset
     680             :     GetOffsetInTableForRow(int iRow, vsi_l_offset *pnOffsetInTableX = nullptr);
     681             : 
     682       27826 :     int HasDeletedFeaturesListed() const
     683             :     {
     684       27826 :         return m_bHasDeletedFeaturesListed;
     685             :     }
     686             : 
     687             :     /* Next call to SelectRow() or GetFieldValue() invalidates previously
     688             :      * returned values */
     689             :     int SelectRow(int iRow);
     690             :     int GetAndSelectNextNonEmptyRow(int iRow);
     691             : 
     692       53852 :     int HasGotError() const
     693             :     {
     694       53852 :         return m_bError;
     695             :     }
     696             : 
     697       38039 :     int GetCurRow() const
     698             :     {
     699       38039 :         return m_nCurRow;
     700             :     }
     701             : 
     702           0 :     int IsCurRowDeleted() const
     703             :     {
     704           0 :         return m_bIsDeleted;
     705             :     }
     706             : 
     707             :     const OGRField *GetFieldValue(int iCol);
     708             :     std::vector<OGRField> GetAllFieldValues();
     709             :     void FreeAllFieldValues(std::vector<OGRField> &asFields);
     710             : 
     711             :     int GetFeatureExtent(const OGRField *psGeomField,
     712             :                          OGREnvelope *psOutFeatureEnvelope);
     713             : 
     714       27229 :     const std::vector<double> &GetSpatialIndexGridResolution() const
     715             :     {
     716       27229 :         return m_adfSpatialIndexGridResolution;
     717             :     }
     718             : 
     719             :     void InstallFilterEnvelope(const OGREnvelope *psFilterEnvelope);
     720             :     int DoesGeometryIntersectsFilterEnvelope(const OGRField *psGeomField);
     721             : 
     722             :     void GetMinMaxProjYForSpatialIndex(double &dfYMin, double &dfYMax) const;
     723             : 
     724             :     bool CreateField(std::unique_ptr<FileGDBField> &&psField);
     725             :     bool DeleteField(int iField);
     726             :     bool AlterField(int iField, const std::string &osName,
     727             :                     const std::string &osAlias, FileGDBFieldType eType,
     728             :                     bool bNullable, int nMaxWidth, const OGRField &sDefault);
     729             :     bool AlterGeomField(const std::string &osName, const std::string &osAlias,
     730             :                         bool bNullable, const std::string &osWKT);
     731             : 
     732             :     bool CreateFeature(const std::vector<OGRField> &asRawFields,
     733             :                        const OGRGeometry *poGeom, int *pnFID = nullptr);
     734             :     bool UpdateFeature(int nFID, const std::vector<OGRField> &asRawFields,
     735             :                        const OGRGeometry *poGeom);
     736             :     bool DeleteFeature(int nFID);
     737             : 
     738             :     bool CheckFreeListConsistency();
     739             :     void DeleteFreeList();
     740             : };
     741             : 
     742             : /************************************************************************/
     743             : /*                           FileGDBSQLOp                               */
     744             : /************************************************************************/
     745             : 
     746             : typedef enum
     747             : {
     748             :     FGSO_ISNOTNULL,
     749             :     FGSO_LT,
     750             :     FGSO_LE,
     751             :     FGSO_EQ,
     752             :     FGSO_GE,
     753             :     FGSO_GT
     754             : } FileGDBSQLOp;
     755             : 
     756             : /************************************************************************/
     757             : /*                           FileGDBIterator                            */
     758             : /************************************************************************/
     759             : 
     760             : class FileGDBIterator
     761             : {
     762             :   public:
     763         880 :     virtual ~FileGDBIterator()
     764         880 :     {
     765         880 :     }
     766             : 
     767             :     virtual FileGDBTable *GetTable() = 0;
     768             :     virtual void Reset() = 0;
     769             :     virtual int GetNextRowSortedByFID() = 0;
     770             :     virtual int GetRowCount();
     771             : 
     772             :     /* Only available on a BuildIsNotNull() iterator */
     773             :     virtual const OGRField *GetMinValue(int &eOutOGRFieldType);
     774             :     virtual const OGRField *GetMaxValue(int &eOutOGRFieldType);
     775             :     /* will reset the iterator */
     776             :     virtual int GetMinMaxSumCount(double &dfMin, double &dfMax, double &dfSum,
     777             :                                   int &nCount);
     778             : 
     779             :     /* Only available on a BuildIsNotNull() or Build() iterator */
     780             :     virtual int GetNextRowSortedByValue();
     781             : 
     782             :     static FileGDBIterator *Build(FileGDBTable *poParent, int nFieldIdx,
     783             :                                   int bAscending, FileGDBSQLOp op,
     784             :                                   OGRFieldType eOGRFieldType,
     785             :                                   const OGRField *psValue);
     786             :     static FileGDBIterator *BuildIsNotNull(FileGDBTable *poParent,
     787             :                                            int nFieldIdx, int bAscending);
     788             :     static FileGDBIterator *BuildNot(FileGDBIterator *poIterBase);
     789             :     static FileGDBIterator *BuildAnd(FileGDBIterator *poIter1,
     790             :                                      FileGDBIterator *poIter2,
     791             :                                      bool bTakeOwnershipOfIterators);
     792             :     static FileGDBIterator *BuildOr(FileGDBIterator *poIter1,
     793             :                                     FileGDBIterator *poIter2,
     794             :                                     int bIteratorAreExclusive = FALSE);
     795             : };
     796             : 
     797             : /************************************************************************/
     798             : /*                      FileGDBSpatialIndexIterator                     */
     799             : /************************************************************************/
     800             : 
     801             : class FileGDBSpatialIndexIterator : virtual public FileGDBIterator
     802             : {
     803             :   public:
     804             :     virtual bool SetEnvelope(const OGREnvelope &sFilterEnvelope) = 0;
     805             : 
     806             :     static FileGDBSpatialIndexIterator *
     807             :     Build(FileGDBTable *poParent, const OGREnvelope &sFilterEnvelope);
     808             : };
     809             : 
     810             : /************************************************************************/
     811             : /*                       FileGDBOGRGeometryConverter                    */
     812             : /************************************************************************/
     813             : 
     814             : class FileGDBOGRGeometryConverter
     815             : {
     816             :   public:
     817         867 :     virtual ~FileGDBOGRGeometryConverter()
     818         867 :     {
     819         867 :     }
     820             : 
     821             :     virtual OGRGeometry *GetAsGeometry(const OGRField *psField) = 0;
     822             : 
     823             :     static FileGDBOGRGeometryConverter *
     824             :     BuildConverter(const FileGDBGeomField *poGeomField);
     825             :     static OGRwkbGeometryType
     826             :     GetGeometryTypeFromESRI(const char *pszESRIGeometryType);
     827             : };
     828             : 
     829             : int FileGDBDoubleDateToOGRDate(double dfVal, bool bHighPrecision,
     830             :                                OGRField *psField);
     831             : int FileGDBDoubleTimeToOGRTime(double dfVal, OGRField *psField);
     832             : int FileGDBDateTimeWithOffsetToOGRDate(double dfVal, int16_t nUTCOffset,
     833             :                                        OGRField *psField);
     834             : 
     835             : } /* namespace OpenFileGDB */
     836             : 
     837             : #endif /* ndef FILEGDBTABLE_H_INCLUDED */

Generated by: LCOV version 1.14