LCOV - code coverage report
Current view: top level - ogr - ogrfeaturedefn.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 338 376 89.9 %
Date: 2025-01-18 12:42:00 Functions: 58 64 90.6 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  The OGRFeatureDefn class implementation.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 1999,  Les Technologies SoftMap Inc.
       9             :  * Copyright (c) 2009-2013, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "cpl_port.h"
      15             : #include "ogr_feature.h"
      16             : 
      17             : #include <algorithm>
      18             : #include <cassert>
      19             : #include <cstring>
      20             : 
      21             : #include "cpl_conv.h"
      22             : #include "cpl_error.h"
      23             : #include "cpl_string.h"
      24             : #include "ogr_api.h"
      25             : #include "ogr_core.h"
      26             : #include "ogr_p.h"
      27             : #include "ograpispy.h"
      28             : 
      29             : /************************************************************************/
      30             : /*                           OGRFeatureDefn()                           */
      31             : /************************************************************************/
      32             : 
      33             : /**
      34             :  * \brief Constructor.
      35             :  *
      36             :  * The OGRFeatureDefn maintains a reference count, but this starts at
      37             :  * zero.  It is mainly intended to represent a count of OGRFeature's
      38             :  * based on this definition.
      39             :  *
      40             :  * This method is the same as the C function OGR_FD_Create().
      41             :  *
      42             :  * @param pszName the name to be assigned to this layer/class.  It does not
      43             :  * need to be unique.
      44             :  */
      45             : 
      46       68375 : OGRFeatureDefn::OGRFeatureDefn(const char *pszName)
      47             : {
      48       68375 :     pszFeatureClassName = CPLStrdup(pszName);
      49             :     apoGeomFieldDefn.emplace_back(
      50       68375 :         std::make_unique<OGRGeomFieldDefn>("", wkbUnknown));
      51       68375 : }
      52             : 
      53             : /************************************************************************/
      54             : /*                           OGR_FD_Create()                            */
      55             : /************************************************************************/
      56             : /**
      57             :  * \brief Create a new feature definition object to hold the field definitions.
      58             :  *
      59             :  * The OGRFeatureDefn maintains a reference count, but this starts at
      60             :  * zero, and should normally be incremented by the owner.
      61             :  *
      62             :  * This function is the same as the C++ method
      63             :  * OGRFeatureDefn::OGRFeatureDefn().
      64             :  *
      65             :  * @param pszName the name to be assigned to this layer/class.  It does not
      66             :  * need to be unique.
      67             :  * @return handle to the newly created feature definition.
      68             :  */
      69             : 
      70         119 : OGRFeatureDefnH OGR_FD_Create(const char *pszName)
      71             : 
      72             : {
      73         119 :     return OGRFeatureDefn::ToHandle(new OGRFeatureDefn(pszName));
      74             : }
      75             : 
      76             : /************************************************************************/
      77             : /*                          ~OGRFeatureDefn()                           */
      78             : /************************************************************************/
      79             : 
      80      120674 : OGRFeatureDefn::~OGRFeatureDefn()
      81             : 
      82             : {
      83       68348 :     if (nRefCount != 0)
      84             :     {
      85          80 :         CPLDebug("OGRFeatureDefn",
      86             :                  "OGRFeatureDefn %s with a ref count of %d deleted!",
      87          80 :                  pszFeatureClassName, nRefCount);
      88             :     }
      89             : 
      90       68348 :     CPLFree(pszFeatureClassName);
      91      120674 : }
      92             : 
      93             : /************************************************************************/
      94             : /*                           OGR_FD_Destroy()                           */
      95             : /************************************************************************/
      96             : /**
      97             :  * \brief Destroy a feature definition object and release all memory associated
      98             :  * with it.
      99             :  *
     100             :  * This function is the same as the C++ method
     101             :  * OGRFeatureDefn::~OGRFeatureDefn().
     102             :  *
     103             :  * @param hDefn handle to the feature definition to be destroyed.
     104             :  */
     105             : 
     106           0 : void OGR_FD_Destroy(OGRFeatureDefnH hDefn)
     107             : 
     108             : {
     109           0 :     delete OGRFeatureDefn::FromHandle(hDefn);
     110           0 : }
     111             : 
     112             : /************************************************************************/
     113             : /*                              Release()                               */
     114             : /************************************************************************/
     115             : 
     116             : /**
     117             :  * \fn void OGRFeatureDefn::Release();
     118             :  *
     119             :  * \brief Drop a reference to this object, and destroy if no longer referenced.
     120             :  */
     121             : 
     122     2438450 : void OGRFeatureDefn::Release()
     123             : 
     124             : {
     125     2438450 :     if (Dereference() <= 0)
     126       67882 :         delete this;
     127     2438450 : }
     128             : 
     129             : /************************************************************************/
     130             : /*                           OGR_FD_Release()                           */
     131             : /************************************************************************/
     132             : 
     133             : /**
     134             :  * \brief Drop a reference, and destroy if unreferenced.
     135             :  *
     136             :  * This function is the same as the C++ method OGRFeatureDefn::Release().
     137             :  *
     138             :  * @param hDefn handle to the feature definition to be released.
     139             :  */
     140             : 
     141      125634 : void OGR_FD_Release(OGRFeatureDefnH hDefn)
     142             : 
     143             : {
     144      125634 :     OGRFeatureDefn::FromHandle(hDefn)->Release();
     145      125634 : }
     146             : 
     147             : /************************************************************************/
     148             : /*                               Clone()                                */
     149             : /************************************************************************/
     150             : 
     151             : /**
     152             :  * \fn OGRFeatureDefn *OGRFeatureDefn::Clone() const;
     153             :  *
     154             :  * \brief Create a copy of this feature definition.
     155             :  *
     156             :  * Creates a deep copy of the feature definition.
     157             :  * The reference counter of the copy is initialized at 0.
     158             :  *
     159             :  * @return the copy.
     160             :  */
     161             : 
     162         625 : OGRFeatureDefn *OGRFeatureDefn::Clone() const
     163             : 
     164             : {
     165         625 :     OGRFeatureDefn *poCopy = new OGRFeatureDefn(GetName());
     166             : 
     167             :     {
     168         625 :         const int nFieldCount = GetFieldCount();
     169         625 :         poCopy->apoFieldDefn.reserve(nFieldCount);
     170        3620 :         for (int i = 0; i < nFieldCount; i++)
     171        2995 :             poCopy->AddFieldDefn(GetFieldDefn(i));
     172             :     }
     173             : 
     174             :     {
     175             :         // Remove the default geometry field created instantiation.
     176         625 :         poCopy->DeleteGeomFieldDefn(0);
     177         625 :         const int nGeomFieldCount = GetGeomFieldCount();
     178         625 :         poCopy->apoGeomFieldDefn.reserve(nGeomFieldCount);
     179         976 :         for (int i = 0; i < nGeomFieldCount; i++)
     180         351 :             poCopy->AddGeomFieldDefn(GetGeomFieldDefn(i));
     181             :     }
     182             : 
     183         625 :     return poCopy;
     184             : }
     185             : 
     186             : /************************************************************************/
     187             : /*                              SetName()                               */
     188             : /************************************************************************/
     189             : 
     190             : /**
     191             :  * \brief Change name of this OGRFeatureDefn.
     192             :  *
     193             :  * To rename a layer, do not use this function directly, but use
     194             :  * OGRLayer::Rename() instead.
     195             :  *
     196             :  * @param pszName feature definition name
     197             :  * @since GDAL 2.3
     198             :  */
     199         260 : void OGRFeatureDefn::SetName(const char *pszName)
     200             : {
     201         260 :     if (m_bSealed)
     202             :     {
     203           1 :         CPLError(CE_Failure, CPLE_AppDefined,
     204             :                  "OGRFeatureDefn::SetName() not allowed on a sealed object");
     205           1 :         return;
     206             :     }
     207         259 :     CPLFree(pszFeatureClassName);
     208         259 :     pszFeatureClassName = CPLStrdup(pszName);
     209             : }
     210             : 
     211             : /************************************************************************/
     212             : /*                              GetName()                               */
     213             : /************************************************************************/
     214             : 
     215             : /**
     216             :  * \fn const char *OGRFeatureDefn::GetName();
     217             :  *
     218             :  * \brief Get name of this OGRFeatureDefn.
     219             :  *
     220             :  * This method is the same as the C function OGR_FD_GetName().
     221             :  *
     222             :  * @return the name.  This name is internal and should not be modified, or
     223             :  * freed.
     224             :  */
     225     1246100 : const char *OGRFeatureDefn::GetName() const
     226             : {
     227     1246100 :     return pszFeatureClassName;
     228             : }
     229             : 
     230             : /************************************************************************/
     231             : /*                           OGR_FD_GetName()                           */
     232             : /************************************************************************/
     233             : /**
     234             :  * \brief Get name of the OGRFeatureDefn passed as an argument.
     235             :  *
     236             :  * This function is the same as the C++ method OGRFeatureDefn::GetName().
     237             :  *
     238             :  * @param hDefn handle to the feature definition to get the name from.
     239             :  * @return the name.  This name is internal and should not be modified, or
     240             :  * freed.
     241             :  */
     242             : 
     243         119 : const char *OGR_FD_GetName(OGRFeatureDefnH hDefn)
     244             : 
     245             : {
     246         119 :     return OGRFeatureDefn::FromHandle(hDefn)->GetName();
     247             : }
     248             : 
     249             : /************************************************************************/
     250             : /*                           GetFieldCount()                            */
     251             : /************************************************************************/
     252             : 
     253             : /**
     254             :  * \fn int OGRFeatureDefn::GetFieldCount() const;
     255             :  *
     256             :  * \brief Fetch number of fields on this feature.
     257             :  *
     258             :  * This method is the same as the C function OGR_FD_GetFieldCount().
     259             :  * @return count of fields.
     260             :  */
     261             : 
     262    46900900 : int OGRFeatureDefn::GetFieldCount() const
     263             : {
     264    46900900 :     return static_cast<int>(apoFieldDefn.size());
     265             : }
     266             : 
     267             : /************************************************************************/
     268             : /*                        OGR_FD_GetFieldCount()                        */
     269             : /************************************************************************/
     270             : 
     271             : /**
     272             :  * \brief Fetch number of fields on the passed feature definition.
     273             :  *
     274             :  * This function is the same as the C++ OGRFeatureDefn::GetFieldCount().
     275             :  *
     276             :  * @param hDefn handle to the feature definition to get the fields count from.
     277             :  * @return count of fields.
     278             :  */
     279             : 
     280       48655 : int OGR_FD_GetFieldCount(OGRFeatureDefnH hDefn)
     281             : 
     282             : {
     283             : #ifdef OGRAPISPY_ENABLED
     284       48655 :     if (bOGRAPISpyEnabled)
     285           6 :         OGRAPISpy_FD_GetFieldCount(hDefn);
     286             : #endif
     287             : 
     288       48655 :     return OGRFeatureDefn::FromHandle(hDefn)->GetFieldCount();
     289             : }
     290             : 
     291             : /************************************************************************/
     292             : /*                            GetFieldDefn()                            */
     293             : /************************************************************************/
     294             : 
     295             : /**
     296             :  * \brief Fetch field definition.
     297             :  *
     298             :  * This method is the same as the C function OGR_FD_GetFieldDefn().
     299             :  *
     300             :  * @param iField the field to fetch, between 0 and GetFieldCount() - 1.
     301             :  *
     302             :  * @return a pointer to an internal field definition object or NULL if invalid
     303             :  * index.  This object should not be modified or freed by the application.
     304             :  */
     305             : 
     306    20782300 : OGRFieldDefn *OGRFeatureDefn::GetFieldDefn(int iField)
     307             : 
     308             : {
     309    20782300 :     if (iField < 0 || iField >= GetFieldCount())
     310             :     {
     311          11 :         CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iField);
     312          11 :         return nullptr;
     313             :     }
     314             : 
     315    20782300 :     return apoFieldDefn[iField].get();
     316             : }
     317             : 
     318             : /**
     319             :  * \brief Fetch field definition.
     320             :  *
     321             :  * This method is the same as the C function OGR_FD_GetFieldDefn().
     322             :  *
     323             :  * @param iField the field to fetch, between 0 and GetFieldCount() - 1.
     324             :  *
     325             :  * @return a pointer to an internal field definition object or NULL if invalid
     326             :  * index.  This object should not be modified or freed by the application.
     327             :  *
     328             :  * @since GDAL 2.3
     329             :  */
     330             : 
     331    18014500 : const OGRFieldDefn *OGRFeatureDefn::GetFieldDefn(int iField) const
     332             : 
     333             : {
     334    18014500 :     if (iField < 0 || iField >= GetFieldCount())
     335             :     {
     336           0 :         CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iField);
     337           0 :         return nullptr;
     338             :     }
     339             : 
     340    18014500 :     return apoFieldDefn[iField].get();
     341             : }
     342             : 
     343             : /************************************************************************/
     344             : /*                        OGR_FD_GetFieldDefn()                         */
     345             : /************************************************************************/
     346             : 
     347             : /**
     348             :  * \brief Fetch field definition of the passed feature definition.
     349             :  *
     350             :  * This function is the same as the C++ method
     351             :  * OGRFeatureDefn::GetFieldDefn().
     352             :  *
     353             :  * @param hDefn handle to the feature definition to get the field definition
     354             :  * from.
     355             :  * @param iField the field to fetch, between 0 and GetFieldCount()-1.
     356             :  *
     357             :  * @return a handle to an internal field definition object or NULL if invalid
     358             :  * index.  This object should not be modified or freed by the application.
     359             :  */
     360             : 
     361      222636 : OGRFieldDefnH OGR_FD_GetFieldDefn(OGRFeatureDefnH hDefn, int iField)
     362             : 
     363             : {
     364      222636 :     OGRFieldDefnH hFieldDefnH = OGRFieldDefn::ToHandle(
     365      222636 :         OGRFeatureDefn::FromHandle(hDefn)->GetFieldDefn(iField));
     366             : 
     367             : #ifdef OGRAPISPY_ENABLED
     368      222636 :     if (bOGRAPISpyEnabled)
     369           2 :         OGRAPISpy_FD_GetFieldDefn(hDefn, iField, hFieldDefnH);
     370             : #endif
     371             : 
     372      222636 :     return hFieldDefnH;
     373             : }
     374             : 
     375             : //! @cond Doxygen_Suppress
     376             : 
     377             : /************************************************************************/
     378             : /*                        ReserveSpaceForFields()                       */
     379             : /************************************************************************/
     380             : 
     381         951 : void OGRFeatureDefn::ReserveSpaceForFields(int nFieldCountIn)
     382             : {
     383         951 :     apoFieldDefn.reserve(nFieldCountIn);
     384         951 : }
     385             : 
     386             : //! @endcond
     387             : 
     388             : /************************************************************************/
     389             : /*                            AddFieldDefn()                            */
     390             : /************************************************************************/
     391             : 
     392             : /**
     393             :  * \brief Add a new field definition.
     394             :  *
     395             :  * To add a new field definition to a layer definition, do not use this
     396             :  * function directly, but use OGRLayer::CreateField() instead.
     397             :  *
     398             :  * This method should only be called while there are no OGRFeature
     399             :  * objects in existence based on this OGRFeatureDefn.  The OGRFieldDefn
     400             :  * passed in is copied, and remains the responsibility of the caller.
     401             :  *
     402             :  * This method is the same as the C function OGR_FD_AddFieldDefn().
     403             :  *
     404             :  * @param poNewDefn the definition of the new field.
     405             :  */
     406             : 
     407      706558 : void OGRFeatureDefn::AddFieldDefn(const OGRFieldDefn *poNewDefn)
     408             : 
     409             : {
     410      706558 :     if (m_bSealed)
     411             :     {
     412           2 :         CPLError(
     413             :             CE_Failure, CPLE_AppDefined,
     414             :             "OGRFeatureDefn::AddFieldDefn() not allowed on a sealed object");
     415           2 :         return;
     416             :     }
     417      706556 :     apoFieldDefn.emplace_back(std::make_unique<OGRFieldDefn>(poNewDefn));
     418             : }
     419             : 
     420             : /**
     421             :  * \brief Add a new field definition taking ownership of the passed field.
     422             :  *
     423             :  * To add a new field definition to a layer definition, do not use this
     424             :  * function directly, but use OGRLayer::CreateField() instead.
     425             :  *
     426             :  * This method should only be called while there are no OGRFeature
     427             :  * objects in existence based on this OGRFeatureDefn.
     428             :  *
     429             :  * @param poNewDefn the definition of the new field.
     430             :  */
     431             : 
     432           6 : void OGRFeatureDefn::AddFieldDefn(std::unique_ptr<OGRFieldDefn> &&poNewDefn)
     433             : {
     434           6 :     if (m_bSealed)
     435             :     {
     436           0 :         CPLError(
     437             :             CE_Failure, CPLE_AppDefined,
     438             :             "OGRFeatureDefn::AddFieldDefn() not allowed on a sealed object");
     439           0 :         return;
     440             :     }
     441           6 :     apoFieldDefn.push_back(std::move(poNewDefn));
     442             : }
     443             : 
     444             : /************************************************************************/
     445             : /*                        OGR_FD_AddFieldDefn()                         */
     446             : /************************************************************************/
     447             : 
     448             : /**
     449             :  * \brief Add a new field definition to the passed feature definition.
     450             :  *
     451             :  * To add a new field definition to a layer definition, do not use this
     452             :  * function directly, but use OGR_L_CreateField() instead.
     453             :  *
     454             :  * This function should only be called while there are no OGRFeature
     455             :  * objects in existence based on this OGRFeatureDefn.  The OGRFieldDefn
     456             :  * passed in is copied, and remains the responsibility of the caller.
     457             :  *
     458             :  * This function is the same as the C++ method OGRFeatureDefn::AddFieldDefn().
     459             :  *
     460             :  * @param hDefn handle to the feature definition to add the field definition
     461             :  * to.
     462             :  * @param hNewField handle to the new field definition.
     463             :  */
     464             : 
     465         414 : void OGR_FD_AddFieldDefn(OGRFeatureDefnH hDefn, OGRFieldDefnH hNewField)
     466             : 
     467             : {
     468         828 :     OGRFeatureDefn::FromHandle(hDefn)->AddFieldDefn(
     469         414 :         OGRFieldDefn::FromHandle(hNewField));
     470         414 : }
     471             : 
     472             : /************************************************************************/
     473             : /*                           DeleteFieldDefn()                          */
     474             : /************************************************************************/
     475             : 
     476             : /**
     477             :  * \brief Delete an existing field definition.
     478             :  *
     479             :  * To delete an existing field definition from a layer definition, do not use
     480             :  * this function directly, but use OGRLayer::DeleteField() instead.
     481             :  *
     482             :  * This method should only be called while there are no OGRFeature
     483             :  * objects in existence based on this OGRFeatureDefn.
     484             :  *
     485             :  * This method is the same as the C function OGR_FD_DeleteFieldDefn().
     486             :  *
     487             :  * @param iField the index of the field definition.
     488             :  * @return OGRERR_NONE in case of success.
     489             :  * @since OGR 1.9.0
     490             :  */
     491             : 
     492          96 : OGRErr OGRFeatureDefn::DeleteFieldDefn(int iField)
     493             : 
     494             : {
     495          96 :     if (m_bSealed)
     496             :     {
     497           1 :         CPLError(
     498             :             CE_Failure, CPLE_AppDefined,
     499             :             "OGRFeatureDefn::DeleteFieldDefn() not allowed on a sealed object");
     500           1 :         return OGRERR_FAILURE;
     501             :     }
     502          95 :     if (iField < 0 || iField >= GetFieldCount())
     503           0 :         return OGRERR_FAILURE;
     504             : 
     505          95 :     apoFieldDefn.erase(apoFieldDefn.begin() + iField);
     506          95 :     return OGRERR_NONE;
     507             : }
     508             : 
     509             : /************************************************************************/
     510             : /*                          StealGeomFieldDefn()                       */
     511             : /************************************************************************/
     512             : 
     513           1 : std::unique_ptr<OGRGeomFieldDefn> OGRFeatureDefn::StealGeomFieldDefn(int iField)
     514             : {
     515           1 :     if (m_bSealed)
     516             :     {
     517           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     518             :                  "OGRFeatureDefn::StealGeomFieldDefn() not allowed on a sealed "
     519             :                  "object");
     520           0 :         return nullptr;
     521             :     }
     522           1 :     if (iField < 0 || iField >= GetGeomFieldCount())
     523           0 :         return nullptr;
     524             : 
     525             :     std::unique_ptr<OGRGeomFieldDefn> poFieldDef =
     526           2 :         std::move(apoGeomFieldDefn.at(iField));
     527           1 :     apoGeomFieldDefn.erase(apoGeomFieldDefn.begin() + iField);
     528           1 :     return poFieldDef;
     529             : }
     530             : 
     531             : /************************************************************************/
     532             : /*                          StealFieldDefn()                           */
     533             : /************************************************************************/
     534             : 
     535          14 : std::unique_ptr<OGRFieldDefn> OGRFeatureDefn::StealFieldDefn(int iField)
     536             : {
     537          14 :     if (iField < 0 || iField >= GetFieldCount())
     538           0 :         return nullptr;
     539             : 
     540          28 :     std::unique_ptr<OGRFieldDefn> poFDef = std::move(apoFieldDefn.at(iField));
     541          14 :     apoFieldDefn.erase(apoFieldDefn.begin() + iField);
     542          14 :     return poFDef;
     543             : }
     544             : 
     545             : /************************************************************************/
     546             : /*                       OGR_FD_DeleteFieldDefn()                       */
     547             : /************************************************************************/
     548             : 
     549             : /**
     550             :  * \brief Delete an existing field definition.
     551             :  *
     552             :  * To delete an existing field definition from a layer definition, do not use
     553             :  * this function directly, but use OGR_L_DeleteField() instead.
     554             :  *
     555             :  * This method should only be called while there are no OGRFeature
     556             :  * objects in existence based on this OGRFeatureDefn.
     557             :  *
     558             :  * This method is the same as the C++ method OGRFeatureDefn::DeleteFieldDefn().
     559             :  *
     560             :  * @param hDefn handle to the feature definition.
     561             :  * @param iField the index of the field definition.
     562             :  * @return OGRERR_NONE in case of success.
     563             :  * @since OGR 1.9.0
     564             :  */
     565             : 
     566           0 : OGRErr OGR_FD_DeleteFieldDefn(OGRFeatureDefnH hDefn, int iField)
     567             : 
     568             : {
     569           0 :     return OGRFeatureDefn::FromHandle(hDefn)->DeleteFieldDefn(iField);
     570             : }
     571             : 
     572             : /************************************************************************/
     573             : /*                         ReorderFieldDefns()                          */
     574             : /************************************************************************/
     575             : 
     576             : /**
     577             :  * \brief Reorder the field definitions in the array of the feature definition
     578             :  *
     579             :  * To reorder the field definitions in a layer definition, do not use this
     580             :  * function directly, but use OGR_L_ReorderFields() instead.
     581             :  *
     582             :  * This method should only be called while there are no OGRFeature
     583             :  * objects in existence based on this OGRFeatureDefn.
     584             :  *
     585             :  * This method is the same as the C function OGR_FD_ReorderFieldDefns().
     586             :  *
     587             :  * @param panMap an array of GetFieldCount() elements which
     588             :  * is a permutation of [0, GetFieldCount()-1]. panMap is such that,
     589             :  * for each field definition at position i after reordering,
     590             :  * its position before reordering was panMap[i].
     591             :  * @return OGRERR_NONE in case of success.
     592             :  * @since OGR 1.9.0
     593             :  */
     594             : 
     595          80 : OGRErr OGRFeatureDefn::ReorderFieldDefns(const int *panMap)
     596             : {
     597          80 :     if (m_bSealed)
     598             :     {
     599           1 :         CPLError(CE_Failure, CPLE_AppDefined,
     600             :                  "OGRFeatureDefn::ReorderFieldDefns() not allowed on a sealed "
     601             :                  "object");
     602           1 :         return OGRERR_FAILURE;
     603             :     }
     604          79 :     const int nFieldCount = GetFieldCount();
     605          79 :     if (nFieldCount == 0)
     606           0 :         return OGRERR_NONE;
     607             : 
     608          79 :     const OGRErr eErr = OGRCheckPermutation(panMap, nFieldCount);
     609          79 :     if (eErr != OGRERR_NONE)
     610           0 :         return eErr;
     611             : 
     612          79 :     std::vector<std::unique_ptr<OGRFieldDefn>> apoFieldDefnNew(nFieldCount);
     613         529 :     for (int i = 0; i < nFieldCount; i++)
     614             :     {
     615         450 :         apoFieldDefnNew[i] = std::move(apoFieldDefn[panMap[i]]);
     616             :     }
     617          79 :     apoFieldDefn = std::move(apoFieldDefnNew);
     618          79 :     return OGRERR_NONE;
     619             : }
     620             : 
     621             : /************************************************************************/
     622             : /*                     OGR_FD_ReorderFieldDefns()                       */
     623             : /************************************************************************/
     624             : 
     625             : /**
     626             :  * \brief Reorder the field definitions in the array of the feature definition
     627             :  *
     628             :  * To reorder the field definitions in a layer definition, do not use this
     629             :  * function directly, but use OGR_L_ReorderFields() instead.
     630             :  *
     631             :  * This method should only be called while there are no OGRFeature
     632             :  * objects in existence based on this OGRFeatureDefn.
     633             :  *
     634             :  * This method is the same as the C++ method
     635             :  * OGRFeatureDefn::ReorderFieldDefns().
     636             :  *
     637             :  * @param hDefn handle to the feature definition.
     638             :  * @param panMap an array of GetFieldCount() elements which
     639             :  * is a permutation of [0, GetFieldCount()-1]. panMap is such that,
     640             :  * for each field definition at position i after reordering,
     641             :  * its position before reordering was panMap[i].
     642             :  * @return OGRERR_NONE in case of success.
     643             :  * @since OGR 2.1.0
     644             :  */
     645             : 
     646           0 : OGRErr OGR_FD_ReorderFieldDefns(OGRFeatureDefnH hDefn, const int *panMap)
     647             : 
     648             : {
     649           0 :     return OGRFeatureDefn::FromHandle(hDefn)->ReorderFieldDefns(panMap);
     650             : }
     651             : 
     652             : /************************************************************************/
     653             : /*                         GetGeomFieldCount()                          */
     654             : /************************************************************************/
     655             : 
     656             : /**
     657             :  * \fn int OGRFeatureDefn::GetGeomFieldCount() const;
     658             :  *
     659             :  * \brief Fetch number of geometry fields on this feature.
     660             :  *
     661             :  * This method is the same as the C function OGR_FD_GetGeomFieldCount().
     662             :  * @return count of geometry fields.
     663             :  *
     664             :  * @since GDAL 1.11
     665             :  */
     666    18443500 : int OGRFeatureDefn::GetGeomFieldCount() const
     667             : {
     668    18443500 :     return static_cast<int>(apoGeomFieldDefn.size());
     669             : }
     670             : 
     671             : /************************************************************************/
     672             : /*                      OGR_FD_GetGeomFieldCount()                      */
     673             : /************************************************************************/
     674             : 
     675             : /**
     676             :  * \brief Fetch number of geometry fields on the passed feature definition.
     677             :  *
     678             :  * This function is the same as the C++ OGRFeatureDefn::GetGeomFieldCount().
     679             :  *
     680             :  * @param hDefn handle to the feature definition to get the fields count from.
     681             :  * @return count of geometry fields.
     682             :  *
     683             :  * @since GDAL 1.11
     684             :  */
     685             : 
     686         306 : int OGR_FD_GetGeomFieldCount(OGRFeatureDefnH hDefn)
     687             : 
     688             : {
     689             : #ifdef OGRAPISPY_ENABLED
     690         306 :     if (bOGRAPISpyEnabled)
     691           2 :         OGRAPISpy_FD_GetGeomFieldCount(hDefn);
     692             : #endif
     693             : 
     694         306 :     return OGRFeatureDefn::FromHandle(hDefn)->GetGeomFieldCount();
     695             : }
     696             : 
     697             : /************************************************************************/
     698             : /*                           GetGeomFieldDefn()                         */
     699             : /************************************************************************/
     700             : 
     701             : /**
     702             :  * \brief Fetch geometry field definition.
     703             :  *
     704             :  * This method is the same as the C function OGR_FD_GetGeomFieldDefn().
     705             :  *
     706             :  * @param iGeomField the geometry field to fetch, between 0 and
     707             :  * GetGeomFieldCount() - 1.
     708             :  *
     709             :  * @return a pointer to an internal field definition object or NULL if invalid
     710             :  * index.  This object should not be modified or freed by the application.
     711             :  *
     712             :  * @since GDAL 1.11
     713             :  */
     714             : 
     715      918348 : OGRGeomFieldDefn *OGRFeatureDefn::GetGeomFieldDefn(int iGeomField)
     716             : 
     717             : {
     718      918348 :     if (iGeomField < 0 || iGeomField >= GetGeomFieldCount())
     719             :     {
     720           2 :         CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iGeomField);
     721           2 :         return nullptr;
     722             :     }
     723             : 
     724      918346 :     return apoGeomFieldDefn[iGeomField].get();
     725             : }
     726             : 
     727             : /**
     728             :  * \brief Fetch geometry field definition.
     729             :  *
     730             :  * This method is the same as the C function OGR_FD_GetGeomFieldDefn().
     731             :  *
     732             :  * @param iGeomField the geometry field to fetch, between 0 and
     733             :  * GetGeomFieldCount() - 1.
     734             :  *
     735             :  * @return a pointer to an internal field definition object or NULL if invalid
     736             :  * index.  This object should not be modified or freed by the application.
     737             :  *
     738             :  * @since GDAL 2.3
     739             :  */
     740             : 
     741      681455 : const OGRGeomFieldDefn *OGRFeatureDefn::GetGeomFieldDefn(int iGeomField) const
     742             : 
     743             : {
     744      681455 :     if (iGeomField < 0 || iGeomField >= GetGeomFieldCount())
     745             :     {
     746           0 :         CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iGeomField);
     747           0 :         return nullptr;
     748             :     }
     749             : 
     750      681455 :     return apoGeomFieldDefn[iGeomField].get();
     751             : }
     752             : 
     753             : /************************************************************************/
     754             : /*                      OGR_FD_GetGeomFieldDefn()                       */
     755             : /************************************************************************/
     756             : 
     757             : /**
     758             :  * \brief Fetch geometry field definition of the passed feature definition.
     759             :  *
     760             :  * This function is the same as the C++ method
     761             :  * OGRFeatureDefn::GetGeomFieldDefn().
     762             :  *
     763             :  * @param hDefn handle to the feature definition to get the field definition
     764             :  * from.
     765             :  * @param iGeomField the geometry field to fetch, between 0 and
     766             :  * GetGeomFieldCount() - 1.
     767             :  *
     768             :  * @return a handle to an internal field definition object or NULL if invalid
     769             :  * index.  This object should not be modified or freed by the application.
     770             :  *
     771             :  * @since GDAL 1.11
     772             :  */
     773             : 
     774         578 : OGRGeomFieldDefnH OGR_FD_GetGeomFieldDefn(OGRFeatureDefnH hDefn, int iGeomField)
     775             : 
     776             : {
     777         578 :     OGRGeomFieldDefnH hGeomField = OGRGeomFieldDefn::ToHandle(
     778         578 :         OGRFeatureDefn::FromHandle(hDefn)->GetGeomFieldDefn(iGeomField));
     779             : 
     780             : #ifdef OGRAPISPY_ENABLED
     781         578 :     if (bOGRAPISpyEnabled)
     782           2 :         OGRAPISpy_FD_GetGeomFieldDefn(hDefn, iGeomField, hGeomField);
     783             : #endif
     784             : 
     785         578 :     return hGeomField;
     786             : }
     787             : 
     788             : /************************************************************************/
     789             : /*                          AddGeomFieldDefn()                          */
     790             : /************************************************************************/
     791             : 
     792             : /**
     793             :  * \brief Add a new geometry field definition.
     794             :  *
     795             :  * To add a new geometry field definition to a layer definition, do not use this
     796             :  * function directly, but use OGRLayer::CreateGeomField() instead.
     797             :  *
     798             :  * This method does an internal copy of the passed geometry field definition,
     799             :  * unless bCopy is set to FALSE (in which case it takes ownership of the
     800             :  * field definition.
     801             :  *
     802             :  * This method should only be called while there are no OGRFeature
     803             :  * objects in existence based on this OGRFeatureDefn.  The OGRGeomFieldDefn
     804             :  * passed in is copied, and remains the responsibility of the caller.
     805             :  *
     806             :  * This method is the same as the C function OGR_FD_AddGeomFieldDefn().
     807             :  *
     808             :  * @param poNewDefn the definition of the new geometry field.
     809             :  *
     810             :  * @since GDAL 1.11
     811             :  */
     812             : 
     813        7132 : void OGRFeatureDefn::AddGeomFieldDefn(const OGRGeomFieldDefn *poNewDefn)
     814             : {
     815        7132 :     if (m_bSealed)
     816             :     {
     817           1 :         CPLError(CE_Failure, CPLE_AppDefined,
     818             :                  "OGRFeatureDefn::AddGeomFieldDefn() not allowed on a sealed "
     819             :                  "object");
     820           1 :         return;
     821             :     }
     822             :     apoGeomFieldDefn.emplace_back(
     823        7131 :         std::make_unique<OGRGeomFieldDefn>(poNewDefn));
     824             : }
     825             : 
     826             : /**
     827             :  * \brief Add a new geometry field definition.
     828             :  *
     829             :  * To add a new geometry field definition to a layer definition, do not use this
     830             :  * function directly, but use OGRLayer::CreateGeomField() instead.
     831             :  *
     832             :  * This method takes ownership of the passed geometry field definition.
     833             :  *
     834             :  * This method should only be called while there are no OGRFeature
     835             :  * objects in existence based on this OGRFeatureDefn.
     836             :  *
     837             :  * @param poNewDefn the definition of the new geometry field.
     838             :  *
     839             :  * @since GDAL 3.4
     840             :  */
     841             : 
     842       11448 : void OGRFeatureDefn::AddGeomFieldDefn(
     843             :     std::unique_ptr<OGRGeomFieldDefn> &&poNewDefn)
     844             : {
     845       11448 :     apoGeomFieldDefn.emplace_back(std::move(poNewDefn));
     846       11448 : }
     847             : 
     848             : /************************************************************************/
     849             : /*                      OGR_FD_AddGeomFieldDefn()                       */
     850             : /************************************************************************/
     851             : 
     852             : /**
     853             :  * \brief Add a new field definition to the passed feature definition.
     854             :  *
     855             :  * To add a new field definition to a layer definition, do not use this
     856             :  * function directly, but use OGR_L_CreateGeomField() instead.
     857             :  *
     858             :  * This function should only be called while there are no OGRFeature
     859             :  * objects in existence based on this OGRFeatureDefn.  The OGRGeomFieldDefn
     860             :  * passed in is copied, and remains the responsibility of the caller.
     861             :  *
     862             :  * This function is the same as the C++ method
     863             :  * OGRFeatureDefn::AddGeomFieldDefn().
     864             :  *
     865             :  * @param hDefn handle to the feature definition to add the geometry field
     866             :  * definition to.
     867             :  * @param hNewGeomField handle to the new field definition.
     868             :  *
     869             :  * @since GDAL 1.11
     870             :  */
     871             : 
     872          11 : void OGR_FD_AddGeomFieldDefn(OGRFeatureDefnH hDefn,
     873             :                              OGRGeomFieldDefnH hNewGeomField)
     874             : 
     875             : {
     876          22 :     OGRFeatureDefn::FromHandle(hDefn)->AddGeomFieldDefn(
     877          11 :         OGRGeomFieldDefn::FromHandle(hNewGeomField));
     878          11 : }
     879             : 
     880             : /************************************************************************/
     881             : /*                         DeleteGeomFieldDefn()                        */
     882             : /************************************************************************/
     883             : 
     884             : /**
     885             :  * \brief Delete an existing geometry field definition.
     886             :  *
     887             :  * To delete an existing field definition from a layer definition, do not use
     888             :  * this function directly, but use OGRLayer::DeleteGeomField() instead.
     889             :  *
     890             :  * This method should only be called while there are no OGRFeature
     891             :  * objects in existence based on this OGRFeatureDefn.
     892             :  *
     893             :  * This method is the same as the C function OGR_FD_DeleteGeomFieldDefn().
     894             :  *
     895             :  * @param iGeomField the index of the geometry field definition.
     896             :  * @return OGRERR_NONE in case of success.
     897             :  *
     898             :  * @since GDAL 1.11
     899             :  */
     900             : 
     901       52010 : OGRErr OGRFeatureDefn::DeleteGeomFieldDefn(int iGeomField)
     902             : 
     903             : {
     904       52010 :     if (m_bSealed)
     905             :     {
     906           1 :         CPLError(CE_Failure, CPLE_AppDefined,
     907             :                  "OGRFeatureDefn::DeleteGeomFieldDefn() not allowed on a "
     908             :                  "sealed object");
     909           1 :         return OGRERR_FAILURE;
     910             :     }
     911       52009 :     if (iGeomField < 0 || iGeomField >= GetGeomFieldCount())
     912           2 :         return OGRERR_FAILURE;
     913             : 
     914       52007 :     apoGeomFieldDefn.erase(apoGeomFieldDefn.begin() + iGeomField);
     915       52007 :     return OGRERR_NONE;
     916             : }
     917             : 
     918             : /************************************************************************/
     919             : /*                     OGR_FD_DeleteGeomFieldDefn()                     */
     920             : /************************************************************************/
     921             : 
     922             : /**
     923             :  * \brief Delete an existing geometry field definition.
     924             :  *
     925             :  * To delete an existing geometry field definition from a layer definition, do
     926             :  * not use this function directly, but use OGR_L_DeleteGeomField() instead
     927             :  * (*not implemented yet*).
     928             :  *
     929             :  * This method should only be called while there are no OGRFeature
     930             :  * objects in existence based on this OGRFeatureDefn.
     931             :  *
     932             :  * This method is the same as the C++ method
     933             :  * OGRFeatureDefn::DeleteGeomFieldDefn().
     934             :  *
     935             :  * @param hDefn handle to the feature definition.
     936             :  * @param iGeomField the index of the geometry field definition.
     937             :  * @return OGRERR_NONE in case of success.
     938             :  *
     939             :  * @since GDAL 1.11
     940             :  */
     941             : 
     942           4 : OGRErr OGR_FD_DeleteGeomFieldDefn(OGRFeatureDefnH hDefn, int iGeomField)
     943             : 
     944             : {
     945           4 :     return OGRFeatureDefn::FromHandle(hDefn)->DeleteGeomFieldDefn(iGeomField);
     946             : }
     947             : 
     948             : /************************************************************************/
     949             : /*                         GetGeomFieldIndex()                          */
     950             : /************************************************************************/
     951             : 
     952             : /**
     953             :  * \brief Find geometry field by name.
     954             :  *
     955             :  * The geometry field index of the first geometry field matching the passed
     956             :  * field name (case insensitively) is returned.
     957             :  *
     958             :  * This method is the same as the C function OGR_FD_GetGeomFieldIndex().
     959             :  *
     960             :  * @param pszGeomFieldName the geometry field name to search for.
     961             :  *
     962             :  * @return the geometry field index, or -1 if no match found.
     963             :  */
     964             : 
     965       26292 : int OGRFeatureDefn::GetGeomFieldIndex(const char *pszGeomFieldName) const
     966             : 
     967             : {
     968       26292 :     const int nGeomFieldCount = GetGeomFieldCount();
     969       43123 :     for (int i = 0; i < nGeomFieldCount; i++)
     970             :     {
     971       34667 :         const OGRGeomFieldDefn *poGFldDefn = GetGeomFieldDefn(i);
     972       69334 :         if (poGFldDefn != nullptr &&
     973       34667 :             EQUAL(pszGeomFieldName, poGFldDefn->GetNameRef()))
     974       17836 :             return i;
     975             :     }
     976             : 
     977        8456 :     return -1;
     978             : }
     979             : 
     980             : /************************************************************************/
     981             : /*                      OGR_FD_GetGeomFieldIndex()                      */
     982             : /************************************************************************/
     983             : /**
     984             :  * \brief Find geometry field by name.
     985             :  *
     986             :  * The geometry field index of the first geometry field matching the passed
     987             :  * field name (case insensitively) is returned.
     988             :  *
     989             :  * This function is the same as the C++ method
     990             :  * OGRFeatureDefn::GetGeomFieldIndex.
     991             :  *
     992             :  * @param hDefn handle to the feature definition to get field index from.
     993             :  * @param pszGeomFieldName the geometry field name to search for.
     994             :  *
     995             :  * @return the geometry field index, or -1 if no match found.
     996             :  */
     997             : 
     998          37 : int OGR_FD_GetGeomFieldIndex(OGRFeatureDefnH hDefn,
     999             :                              const char *pszGeomFieldName)
    1000             : 
    1001             : {
    1002             : #ifdef OGRAPISPY_ENABLED
    1003          37 :     if (bOGRAPISpyEnabled)
    1004           2 :         OGRAPISpy_FD_GetGeomFieldIndex(hDefn, pszGeomFieldName);
    1005             : #endif
    1006             : 
    1007          74 :     return OGRFeatureDefn::FromHandle(hDefn)->GetGeomFieldIndex(
    1008          37 :         pszGeomFieldName);
    1009             : }
    1010             : 
    1011             : /************************************************************************/
    1012             : /*                            GetGeomType()                             */
    1013             : /************************************************************************/
    1014             : 
    1015             : /**
    1016             :  * \fn OGRwkbGeometryType OGRFeatureDefn::GetGeomType() const;
    1017             :  *
    1018             :  * \brief Fetch the geometry base type.
    1019             :  *
    1020             :  * Note that some drivers are unable to determine a specific geometry
    1021             :  * type for a layer, in which case wkbUnknown is returned.  A value of
    1022             :  * wkbNone indicates no geometry is available for the layer at all.
    1023             :  * Many drivers do not properly mark the geometry
    1024             :  * type as 25D even if some or all geometries are in fact 25D.  A few (broken)
    1025             :  * drivers return wkbPolygon for layers that also include wkbMultiPolygon.
    1026             :  *
    1027             :  * Starting with GDAL 1.11, this method returns GetGeomFieldDefn(0)->GetType().
    1028             :  *
    1029             :  * This method is the same as the C function OGR_FD_GetGeomType().
    1030             :  *
    1031             :  * @return the base type for all geometry related to this definition.
    1032             :  */
    1033      555472 : OGRwkbGeometryType OGRFeatureDefn::GetGeomType() const
    1034             : {
    1035      555472 :     if (GetGeomFieldCount() == 0)
    1036        2040 :         return wkbNone;
    1037      553432 :     const OGRGeomFieldDefn *poGFldDefn = GetGeomFieldDefn(0);
    1038      553432 :     if (poGFldDefn == nullptr)
    1039           0 :         return wkbNone;
    1040      553432 :     OGRwkbGeometryType eType = poGFldDefn->GetType();
    1041      553437 :     if (eType == (/*wkbUnknown |*/ wkb25DBitInternalUse) &&
    1042           5 :         CPLTestBool(CPLGetConfigOption("QGIS_HACK", "NO")))
    1043           0 :         eType = wkbUnknown;
    1044      553432 :     return eType;
    1045             : }
    1046             : 
    1047             : /************************************************************************/
    1048             : /*                         OGR_FD_GetGeomType()                         */
    1049             : /************************************************************************/
    1050             : /**
    1051             :  * \brief Fetch the geometry base type of the passed feature definition.
    1052             :  *
    1053             :  * This function is the same as the C++ method OGRFeatureDefn::GetGeomType().
    1054             :  *
    1055             :  * Starting with GDAL 1.11, this method returns GetGeomFieldDefn(0)->GetType().
    1056             :  *
    1057             :  * @param hDefn handle to the feature definition to get the geometry type from.
    1058             :  * @return the base type for all geometry related to this definition.
    1059             :  */
    1060             : 
    1061        4409 : OGRwkbGeometryType OGR_FD_GetGeomType(OGRFeatureDefnH hDefn)
    1062             : 
    1063             : {
    1064        4409 :     OGRwkbGeometryType eType = OGRFeatureDefn::FromHandle(hDefn)->GetGeomType();
    1065        4409 :     if (OGR_GT_IsNonLinear(eType) && !OGRGetNonLinearGeometriesEnabledFlag())
    1066             :     {
    1067           1 :         eType = OGR_GT_GetLinear(eType);
    1068             :     }
    1069             : #ifdef OGRAPISPY_ENABLED
    1070        4409 :     if (bOGRAPISpyEnabled)
    1071           2 :         OGRAPISpy_FD_GetGeomType(hDefn);
    1072             : #endif
    1073             : 
    1074        4409 :     return eType;
    1075             : }
    1076             : 
    1077             : /************************************************************************/
    1078             : /*                            SetGeomType()                             */
    1079             : /************************************************************************/
    1080             : 
    1081             : /**
    1082             :  * \brief Assign the base geometry type for this layer.
    1083             :  *
    1084             :  * All geometry objects using this type must be of the defined type or
    1085             :  * a derived type.  The default upon creation is wkbUnknown which allows for
    1086             :  * any geometry type.  The geometry type should generally not be changed
    1087             :  * after any OGRFeatures have been created against this definition.
    1088             :  *
    1089             :  * This method is the same as the C function OGR_FD_SetGeomType().
    1090             :  *
    1091             :  * Starting with GDAL 1.11, this method calls GetGeomFieldDefn(0)->SetType().
    1092             :  *
    1093             :  * @param eNewType the new type to assign.
    1094             :  */
    1095             : 
    1096       73025 : void OGRFeatureDefn::SetGeomType(OGRwkbGeometryType eNewType)
    1097             : 
    1098             : {
    1099       73025 :     if (m_bSealed)
    1100             :     {
    1101           0 :         CPLError(
    1102             :             CE_Failure, CPLE_AppDefined,
    1103             :             "OGRFeatureDefn::SetGeomType() not allowed on a sealed object");
    1104           0 :         return;
    1105             :     }
    1106       73025 :     const int nGeomFieldCount = GetGeomFieldCount();
    1107       73025 :     if (nGeomFieldCount > 0)
    1108             :     {
    1109       67558 :         if (nGeomFieldCount == 1 && eNewType == wkbNone)
    1110       50684 :             DeleteGeomFieldDefn(0);
    1111             :         else
    1112       16874 :             GetGeomFieldDefn(0)->SetType(eNewType);
    1113             :     }
    1114        5467 :     else if (eNewType != wkbNone)
    1115             :     {
    1116        3434 :         OGRGeomFieldDefn oGeomFieldDefn("", eNewType);
    1117        1717 :         AddGeomFieldDefn(&oGeomFieldDefn);
    1118             :     }
    1119             : }
    1120             : 
    1121             : /************************************************************************/
    1122             : /*                         OGR_FD_SetGeomType()                         */
    1123             : /************************************************************************/
    1124             : 
    1125             : /**
    1126             :  * \brief Assign the base geometry type for the passed layer (the same as the
    1127             :  * feature definition).
    1128             :  *
    1129             :  * All geometry objects using this type must be of the defined type or
    1130             :  * a derived type.  The default upon creation is wkbUnknown which allows for
    1131             :  * any geometry type.  The geometry type should generally not be changed
    1132             :  * after any OGRFeatures have been created against this definition.
    1133             :  *
    1134             :  * This function is the same as the C++ method OGRFeatureDefn::SetGeomType().
    1135             :  *
    1136             :  * Starting with GDAL 1.11, this method calls GetGeomFieldDefn(0)->SetType().
    1137             :  *
    1138             :  * @param hDefn handle to the layer or feature definition to set the geometry
    1139             :  * type to.
    1140             :  * @param eType the new type to assign.
    1141             :  */
    1142             : 
    1143          20 : void OGR_FD_SetGeomType(OGRFeatureDefnH hDefn, OGRwkbGeometryType eType)
    1144             : 
    1145             : {
    1146          20 :     OGRFeatureDefn::FromHandle(hDefn)->SetGeomType(eType);
    1147          20 : }
    1148             : 
    1149             : /************************************************************************/
    1150             : /*                             Reference()                              */
    1151             : /************************************************************************/
    1152             : 
    1153             : /**
    1154             :  * \fn int OGRFeatureDefn::Reference();
    1155             :  *
    1156             :  * \brief Increments the reference count by one.
    1157             :  *
    1158             :  * The reference count is used keep track of the number of OGRFeature
    1159             :  * objects referencing this definition.
    1160             :  *
    1161             :  * This method is the same as the C function OGR_FD_Reference().
    1162             :  *
    1163             :  * @return the updated reference count.
    1164             :  */
    1165             : 
    1166             : /************************************************************************/
    1167             : /*                          OGR_FD_Reference()                          */
    1168             : /************************************************************************/
    1169             : /**
    1170             :  * \brief Increments the reference count by one.
    1171             :  *
    1172             :  * The reference count is used keep track of the number of OGRFeature
    1173             :  * objects referencing this definition.
    1174             :  *
    1175             :  * This function is the same as the C++ method OGRFeatureDefn::Reference().
    1176             :  *
    1177             :  * @param hDefn handle to the feature definition on witch OGRFeature are
    1178             :  * based on.
    1179             :  * @return the updated reference count.
    1180             :  */
    1181             : 
    1182      125655 : int OGR_FD_Reference(OGRFeatureDefnH hDefn)
    1183             : 
    1184             : {
    1185      125655 :     return OGRFeatureDefn::FromHandle(hDefn)->Reference();
    1186             : }
    1187             : 
    1188             : /************************************************************************/
    1189             : /*                            Dereference()                             */
    1190             : /************************************************************************/
    1191             : 
    1192             : /**
    1193             :  * \fn int OGRFeatureDefn::Dereference();
    1194             :  *
    1195             :  * \brief Decrements the reference count by one.
    1196             :  *
    1197             :  * This method is the same as the C function OGR_FD_Dereference().
    1198             :  *
    1199             :  * @return the updated reference count.
    1200             :  */
    1201             : 
    1202             : /************************************************************************/
    1203             : /*                         OGR_FD_Dereference()                         */
    1204             : /************************************************************************/
    1205             : 
    1206             : /**
    1207             :  * \brief Decrements the reference count by one.
    1208             :  *
    1209             :  * This function is the same as the C++ method OGRFeatureDefn::Dereference().
    1210             :  *
    1211             :  * @param hDefn handle to the feature definition on witch OGRFeature are
    1212             :  * based on.
    1213             :  * @return the updated reference count.
    1214             :  */
    1215             : 
    1216           0 : int OGR_FD_Dereference(OGRFeatureDefnH hDefn)
    1217             : 
    1218             : {
    1219           0 :     return OGRFeatureDefn::FromHandle(hDefn)->Dereference();
    1220             : }
    1221             : 
    1222             : /************************************************************************/
    1223             : /*                         GetReferenceCount()                          */
    1224             : /************************************************************************/
    1225             : 
    1226             : /**
    1227             :  * \fn int OGRFeatureDefn::GetReferenceCount();
    1228             :  *
    1229             :  * \brief Fetch current reference count.
    1230             :  *
    1231             :  * This method is the same as the C function OGR_FD_GetReferenceCount().
    1232             :  *
    1233             :  * @return the current reference count.
    1234             :  */
    1235             : 
    1236             : /************************************************************************/
    1237             : /*                      OGR_FD_GetReferenceCount()                      */
    1238             : /************************************************************************/
    1239             : 
    1240             : /**
    1241             :  * \brief Fetch current reference count.
    1242             :  *
    1243             :  * This function is the same as the C++ method
    1244             :  * OGRFeatureDefn::GetReferenceCount().
    1245             :  *
    1246             :  * @param hDefn handle to the feature definition on witch OGRFeature are
    1247             :  * based on.
    1248             :  * @return the current reference count.
    1249             :  */
    1250             : 
    1251           3 : int OGR_FD_GetReferenceCount(OGRFeatureDefnH hDefn)
    1252             : 
    1253             : {
    1254           3 :     return OGRFeatureDefn::FromHandle(hDefn)->GetReferenceCount();
    1255             : }
    1256             : 
    1257             : /************************************************************************/
    1258             : /*                           GetFieldIndex()                            */
    1259             : /************************************************************************/
    1260             : 
    1261             : /**
    1262             :  * \brief Find field by name.
    1263             :  *
    1264             :  * The field index of the first field matching the passed field name (case
    1265             :  * insensitively) is returned.
    1266             :  *
    1267             :  * This method is the same as the C function OGR_FD_GetFieldIndex().
    1268             :  *
    1269             :  * @param pszFieldName the field name to search for.
    1270             :  *
    1271             :  * @return the field index, or -1 if no match found.
    1272             :  */
    1273             : 
    1274     2524310 : int OGRFeatureDefn::GetFieldIndex(const char *pszFieldName) const
    1275             : 
    1276             : {
    1277     2524310 :     const int nFieldCount = GetFieldCount();
    1278    17834800 :     for (int i = 0; i < nFieldCount; i++)
    1279             :     {
    1280    17749200 :         const OGRFieldDefn *poFDefn = GetFieldDefn(i);
    1281    17749200 :         if (poFDefn != nullptr && EQUAL(pszFieldName, poFDefn->GetNameRef()))
    1282     2438730 :             return i;
    1283             :     }
    1284             : 
    1285       85574 :     return -1;
    1286             : }
    1287             : 
    1288             : /************************************************************************/
    1289             : /*                      GetFieldIndexCaseSensitive()                    */
    1290             : /************************************************************************/
    1291             : 
    1292             : /**
    1293             :  * \brief Find field by name, in a case sensitive way.
    1294             :  *
    1295             :  * The field index of the first field matching the passed field name is
    1296             :  * returned.
    1297             :  *
    1298             :  * @param pszFieldName the field name to search for.
    1299             :  *
    1300             :  * @return the field index, or -1 if no match found.
    1301             :  */
    1302             : 
    1303       10112 : int OGRFeatureDefn::GetFieldIndexCaseSensitive(const char *pszFieldName) const
    1304             : 
    1305             : {
    1306       10112 :     const int nFieldCount = GetFieldCount();
    1307       62347 :     for (int i = 0; i < nFieldCount; i++)
    1308             :     {
    1309       60592 :         const OGRFieldDefn *poFDefn = GetFieldDefn(i);
    1310      121184 :         if (poFDefn != nullptr &&
    1311       60592 :             strcmp(pszFieldName, poFDefn->GetNameRef()) == 0)
    1312             :         {
    1313        8357 :             return i;
    1314             :         }
    1315             :     }
    1316             : 
    1317        1755 :     return -1;
    1318             : }
    1319             : 
    1320             : /************************************************************************/
    1321             : /*                        OGR_FD_GetFieldIndex()                        */
    1322             : /************************************************************************/
    1323             : /**
    1324             :  * \brief Find field by name.
    1325             :  *
    1326             :  * The field index of the first field matching the passed field name (case
    1327             :  * insensitively) is returned.
    1328             :  *
    1329             :  * This function is the same as the C++ method OGRFeatureDefn::GetFieldIndex.
    1330             :  *
    1331             :  * @param hDefn handle to the feature definition to get field index from.
    1332             :  * @param pszFieldName the field name to search for.
    1333             :  *
    1334             :  * @return the field index, or -1 if no match found.
    1335             :  */
    1336             : 
    1337        1934 : int OGR_FD_GetFieldIndex(OGRFeatureDefnH hDefn, const char *pszFieldName)
    1338             : 
    1339             : {
    1340             : #ifdef OGRAPISPY_ENABLED
    1341        1934 :     if (bOGRAPISpyEnabled)
    1342           2 :         OGRAPISpy_FD_GetFieldIndex(hDefn, pszFieldName);
    1343             : #endif
    1344             : 
    1345        1934 :     return OGRFeatureDefn::FromHandle(hDefn)->GetFieldIndex(pszFieldName);
    1346             : }
    1347             : 
    1348             : /************************************************************************/
    1349             : /*                         IsGeometryIgnored()                          */
    1350             : /************************************************************************/
    1351             : 
    1352             : /**
    1353             :  * \fn int OGRFeatureDefn::IsGeometryIgnored() const;
    1354             :  *
    1355             :  * \brief Determine whether the geometry can be omitted when fetching features
    1356             :  *
    1357             :  * This method is the same as the C function OGR_FD_IsGeometryIgnored().
    1358             :  *
    1359             :  * Starting with GDAL 1.11, this method returns
    1360             :  * GetGeomFieldDefn(0)->IsIgnored().
    1361             :  *
    1362             :  * @return ignore state
    1363             :  */
    1364             : 
    1365       91663 : int OGRFeatureDefn::IsGeometryIgnored() const
    1366             : {
    1367       91663 :     if (GetGeomFieldCount() == 0)
    1368         183 :         return FALSE;
    1369       91480 :     const OGRGeomFieldDefn *poGFldDefn = GetGeomFieldDefn(0);
    1370       91480 :     if (poGFldDefn == nullptr)
    1371           0 :         return FALSE;
    1372       91480 :     return poGFldDefn->IsIgnored();
    1373             : }
    1374             : 
    1375             : /************************************************************************/
    1376             : /*                      OGR_FD_IsGeometryIgnored()                      */
    1377             : /************************************************************************/
    1378             : 
    1379             : /**
    1380             :  * \brief Determine whether the geometry can be omitted when fetching features
    1381             :  *
    1382             :  * This function is the same as the C++ method
    1383             :  * OGRFeatureDefn::IsGeometryIgnored().
    1384             :  *
    1385             :  * Starting with GDAL 1.11, this method returns
    1386             :  * GetGeomFieldDefn(0)->IsIgnored().
    1387             :  *
    1388             :  * @param hDefn handle to the feature definition on witch OGRFeature are
    1389             :  * based on.
    1390             :  * @return ignore state
    1391             :  */
    1392             : 
    1393           6 : int OGR_FD_IsGeometryIgnored(OGRFeatureDefnH hDefn)
    1394             : {
    1395           6 :     return OGRFeatureDefn::FromHandle(hDefn)->IsGeometryIgnored();
    1396             : }
    1397             : 
    1398             : /************************************************************************/
    1399             : /*                         SetGeometryIgnored()                         */
    1400             : /************************************************************************/
    1401             : 
    1402             : /**
    1403             :  * \fn void OGRFeatureDefn::SetGeometryIgnored( int bIgnore );
    1404             :  *
    1405             :  * \brief Set whether the geometry can be omitted when fetching features
    1406             :  *
    1407             :  * This method is the same as the C function OGR_FD_SetGeometryIgnored().
    1408             :  *
    1409             :  * Starting with GDAL 1.11, this method calls GetGeomFieldDefn(0)->SetIgnored().
    1410             :  *
    1411             :  * @param bIgnore ignore state
    1412             :  */
    1413             : 
    1414         967 : void OGRFeatureDefn::SetGeometryIgnored(int bIgnore)
    1415             : {
    1416         967 :     if (GetGeomFieldCount() > 0)
    1417             :     {
    1418         781 :         OGRGeomFieldDefn *poGFldDefn = GetGeomFieldDefn(0);
    1419         781 :         if (poGFldDefn != nullptr)
    1420         781 :             poGFldDefn->SetIgnored(bIgnore);
    1421             :     }
    1422         967 : }
    1423             : 
    1424             : /************************************************************************/
    1425             : /*                      OGR_FD_SetGeometryIgnored()                     */
    1426             : /************************************************************************/
    1427             : 
    1428             : /**
    1429             :  * \brief Set whether the geometry can be omitted when fetching features
    1430             :  *
    1431             :  * This function is the same as the C++ method
    1432             :  * OGRFeatureDefn::SetGeometryIgnored().
    1433             :  *
    1434             :  * Starting with GDAL 1.11, this method calls GetGeomFieldDefn(0)->SetIgnored().
    1435             :  *
    1436             :  * @param hDefn handle to the feature definition on witch OGRFeature are
    1437             :  * based on.
    1438             :  * @param bIgnore ignore state
    1439             :  */
    1440             : 
    1441           3 : void OGR_FD_SetGeometryIgnored(OGRFeatureDefnH hDefn, int bIgnore)
    1442             : {
    1443           3 :     OGRFeatureDefn::FromHandle(hDefn)->SetGeometryIgnored(bIgnore);
    1444           3 : }
    1445             : 
    1446             : /************************************************************************/
    1447             : /*                           IsStyleIgnored()                           */
    1448             : /************************************************************************/
    1449             : 
    1450             : /**
    1451             :  * \fn int OGRFeatureDefn::IsStyleIgnored() const;
    1452             :  *
    1453             :  * \brief Determine whether the style can be omitted when fetching features
    1454             :  *
    1455             :  * This method is the same as the C function OGR_FD_IsStyleIgnored().
    1456             :  *
    1457             :  * @return ignore state
    1458             :  */
    1459             : 
    1460             : /************************************************************************/
    1461             : /*                       OGR_FD_IsStyleIgnored()                        */
    1462             : /************************************************************************/
    1463             : 
    1464             : /**
    1465             :  * \brief Determine whether the style can be omitted when fetching features
    1466             :  *
    1467             :  * This function is the same as the C++ method
    1468             :  * OGRFeatureDefn::IsStyleIgnored().
    1469             :  *
    1470             :  * @param hDefn handle to the feature definition on which OGRFeature are
    1471             :  * based on.
    1472             :  * @return ignore state
    1473             :  */
    1474             : 
    1475           2 : int OGR_FD_IsStyleIgnored(OGRFeatureDefnH hDefn)
    1476             : {
    1477           2 :     return OGRFeatureDefn::FromHandle(hDefn)->IsStyleIgnored();
    1478             : }
    1479             : 
    1480             : /************************************************************************/
    1481             : /*                          SetStyleIgnored()                           */
    1482             : /************************************************************************/
    1483             : 
    1484             : /**
    1485             :  * \fn void OGRFeatureDefn::SetStyleIgnored( int bIgnore );
    1486             :  *
    1487             :  * \brief Set whether the style can be omitted when fetching features
    1488             :  *
    1489             :  * This method is the same as the C function OGR_FD_SetStyleIgnored().
    1490             :  *
    1491             :  * @param bIgnore ignore state
    1492             :  */
    1493             : 
    1494             : /************************************************************************/
    1495             : /*                       OGR_FD_SetStyleIgnored()                       */
    1496             : /************************************************************************/
    1497             : 
    1498             : /**
    1499             :  * \brief Set whether the style can be omitted when fetching features
    1500             :  *
    1501             :  * This function is the same as the C++ method
    1502             :  * OGRFeatureDefn::SetStyleIgnored().
    1503             :  *
    1504             :  * @param hDefn handle to the feature definition on witch OGRFeature are
    1505             :  * based on.
    1506             :  * @param bIgnore ignore state
    1507             :  */
    1508             : 
    1509           0 : void OGR_FD_SetStyleIgnored(OGRFeatureDefnH hDefn, int bIgnore)
    1510             : {
    1511           0 :     OGRFeatureDefn::FromHandle(hDefn)->SetStyleIgnored(CPL_TO_BOOL(bIgnore));
    1512           0 : }
    1513             : 
    1514             : /************************************************************************/
    1515             : /*                         CreateFeatureDefn()                          */
    1516             : /************************************************************************/
    1517             : 
    1518             : /** Create a new feature definition object.
    1519             :  * @param pszName name
    1520             :  * @return new feature definition object.
    1521             :  */
    1522           1 : OGRFeatureDefn *OGRFeatureDefn::CreateFeatureDefn(const char *pszName)
    1523             : 
    1524             : {
    1525           1 :     return new OGRFeatureDefn(pszName);
    1526             : }
    1527             : 
    1528             : /************************************************************************/
    1529             : /*                         DestroyFeatureDefn()                         */
    1530             : /************************************************************************/
    1531             : 
    1532             : /** Destroy a feature definition.
    1533             :  * @param poDefn feature definition.
    1534             :  */
    1535           0 : void OGRFeatureDefn::DestroyFeatureDefn(OGRFeatureDefn *poDefn)
    1536             : 
    1537             : {
    1538           0 :     delete poDefn;
    1539           0 : }
    1540             : 
    1541             : /************************************************************************/
    1542             : /*                             IsSame()                                 */
    1543             : /************************************************************************/
    1544             : 
    1545             : /**
    1546             :  * \brief Test if the feature definition is identical to the other one.
    1547             :  *
    1548             :  * @param poOtherFeatureDefn the other feature definition to compare to.
    1549             :  * @return TRUE if the feature definition is identical to the other one.
    1550             :  */
    1551             : 
    1552         421 : int OGRFeatureDefn::IsSame(const OGRFeatureDefn *poOtherFeatureDefn) const
    1553             : {
    1554         421 :     const int nFieldCount = GetFieldCount();
    1555         421 :     const int nGeomFieldCount = GetGeomFieldCount();
    1556         421 :     if (strcmp(GetName(), poOtherFeatureDefn->GetName()) == 0 &&
    1557         780 :         nFieldCount == poOtherFeatureDefn->GetFieldCount() &&
    1558         359 :         nGeomFieldCount == poOtherFeatureDefn->GetGeomFieldCount())
    1559             :     {
    1560         904 :         for (int i = 0; i < nFieldCount; i++)
    1561             :         {
    1562         619 :             const OGRFieldDefn *poFldDefn = GetFieldDefn(i);
    1563             :             const OGRFieldDefn *poOtherFldDefn =
    1564         619 :                 poOtherFeatureDefn->GetFieldDefn(i);
    1565         619 :             if (!poFldDefn->IsSame(poOtherFldDefn))
    1566             :             {
    1567           3 :                 return FALSE;
    1568             :             }
    1569             :         }
    1570         597 :         for (int i = 0; i < nGeomFieldCount; i++)
    1571             :         {
    1572         337 :             const OGRGeomFieldDefn *poGFldDefn = GetGeomFieldDefn(i);
    1573             :             const OGRGeomFieldDefn *poOtherGFldDefn =
    1574         337 :                 poOtherFeatureDefn->GetGeomFieldDefn(i);
    1575         337 :             if (!poGFldDefn->IsSame(poOtherGFldDefn))
    1576             :             {
    1577          25 :                 return FALSE;
    1578             :             }
    1579             :         }
    1580         260 :         return TRUE;
    1581             :     }
    1582         133 :     return FALSE;
    1583             : }
    1584             : 
    1585             : /************************************************************************/
    1586             : /*                           OGR_FD_IsSame()                            */
    1587             : /************************************************************************/
    1588             : 
    1589             : /**
    1590             :  * \brief Test if the feature definition is identical to the other one.
    1591             :  *
    1592             :  * @param hFDefn handle to the feature definition on witch OGRFeature are
    1593             :  * based on.
    1594             :  * @param hOtherFDefn handle to the other feature definition to compare to.
    1595             :  * @return TRUE if the feature definition is identical to the other one.
    1596             :  *
    1597             :  * @since OGR 1.11
    1598             :  */
    1599             : 
    1600          11 : int OGR_FD_IsSame(OGRFeatureDefnH hFDefn, OGRFeatureDefnH hOtherFDefn)
    1601             : {
    1602          11 :     VALIDATE_POINTER1(hFDefn, "OGR_FD_IsSame", FALSE);
    1603          11 :     VALIDATE_POINTER1(hOtherFDefn, "OGR_FD_IsSame", FALSE);
    1604             : 
    1605          22 :     return OGRFeatureDefn::FromHandle(hFDefn)->IsSame(
    1606          11 :         OGRFeatureDefn::FromHandle(hOtherFDefn));
    1607             : }
    1608             : 
    1609             : /************************************************************************/
    1610             : /*                      ComputeMapForSetFrom()                          */
    1611             : /************************************************************************/
    1612             : 
    1613             : /**
    1614             :  * \brief Compute the map from source to target field that can be passed to
    1615             :  * SetFrom().
    1616             :  *
    1617             :  * @param poSrcFDefn the feature definition of source features later passed to
    1618             :  * SetFrom()
    1619             :  *
    1620             :  * @param bForgiving true if the operation should continue despite lacking
    1621             :  * output fields matching some of the source fields.
    1622             :  *
    1623             :  * @return an array of size poSrcFDefn->GetFieldCount() if everything succeeds,
    1624             :  * or empty in case a source field definition was not found in the target layer
    1625             :  * and bForgiving == true.
    1626             :  *
    1627             :  * @since GDAL 2.3
    1628             :  */
    1629             : 
    1630             : std::vector<int>
    1631        6357 : OGRFeatureDefn::ComputeMapForSetFrom(const OGRFeatureDefn *poSrcFDefn,
    1632             :                                      bool bForgiving) const
    1633             : {
    1634       12714 :     std::map<CPLString, int> oMapNameToTargetFieldIndex;
    1635       12714 :     std::map<CPLString, int> oMapNameToTargetFieldIndexUC;
    1636        6357 :     const int nFieldCount = GetFieldCount();
    1637       94833 :     for (int i = 0; i < nFieldCount; i++)
    1638             :     {
    1639       88476 :         const OGRFieldDefn *poFldDefn = GetFieldDefn(i);
    1640       88476 :         if (poFldDefn == nullptr)
    1641           0 :             continue;
    1642       88476 :         const char *pszName = poFldDefn->GetNameRef();
    1643             : 
    1644             :         // In the insane case where there are several matches, arbitrarily
    1645             :         // decide for the first one (preserve past behavior)
    1646       88476 :         if (oMapNameToTargetFieldIndex.find(pszName) ==
    1647      176952 :             oMapNameToTargetFieldIndex.end())
    1648             :         {
    1649       88476 :             oMapNameToTargetFieldIndex[pszName] = i;
    1650             :         }
    1651             :     }
    1652       12714 :     std::vector<int> aoMapSrcToTargetIdx;
    1653        6357 :     const int nSrcFieldCount = poSrcFDefn->GetFieldCount();
    1654        6357 :     aoMapSrcToTargetIdx.resize(nSrcFieldCount);
    1655       94026 :     for (int i = 0; i < nSrcFieldCount; i++)
    1656             :     {
    1657       87669 :         const OGRFieldDefn *poSrcFldDefn = poSrcFDefn->GetFieldDefn(i);
    1658       87669 :         if (poSrcFldDefn == nullptr)
    1659           0 :             continue;
    1660       87669 :         const char *pszSrcName = poSrcFldDefn->GetNameRef();
    1661             : 
    1662       87669 :         auto oIter = oMapNameToTargetFieldIndex.find(pszSrcName);
    1663       87669 :         if (oIter == oMapNameToTargetFieldIndex.end())
    1664             :         {
    1665             :             // Build case insensitive map only if needed
    1666        4954 :             if (oMapNameToTargetFieldIndexUC.empty())
    1667             :             {
    1668        6935 :                 for (int j = 0; j < nFieldCount; j++)
    1669             :                 {
    1670        5694 :                     const OGRFieldDefn *poFldDefn = GetFieldDefn(j);
    1671        5694 :                     if (poFldDefn == nullptr)
    1672           0 :                         continue;
    1673             :                     oMapNameToTargetFieldIndexUC
    1674        5694 :                         [CPLString(poFldDefn->GetNameRef()).toupper()] = j;
    1675             :                 }
    1676             :             }
    1677             :             oIter = oMapNameToTargetFieldIndexUC.find(
    1678        4954 :                 CPLString(pszSrcName).toupper());
    1679        4954 :             if (oIter == oMapNameToTargetFieldIndexUC.end())
    1680             :             {
    1681        1846 :                 if (!bForgiving)
    1682             :                 {
    1683           0 :                     return std::vector<int>();
    1684             :                 }
    1685        1846 :                 aoMapSrcToTargetIdx[i] = -1;
    1686             :             }
    1687             :             else
    1688             :             {
    1689        3108 :                 aoMapSrcToTargetIdx[i] = oIter->second;
    1690             :             }
    1691             :         }
    1692             :         else
    1693             :         {
    1694       82715 :             aoMapSrcToTargetIdx[i] = oIter->second;
    1695             :         }
    1696             :     }
    1697        6357 :     return aoMapSrcToTargetIdx;
    1698             : }
    1699             : 
    1700             : /************************************************************************/
    1701             : /*                       OGRFeatureDefn::Seal()                         */
    1702             : /************************************************************************/
    1703             : 
    1704             : /** Seal a OGRFeatureDefn.
    1705             :  *
    1706             :  * A sealed OGRFeatureDefn can not be modified while it is sealed.
    1707             :  *
    1708             :  * This method also call OGRFieldDefn::Seal() and OGRGeomFieldDefn::Seal()
    1709             :  * on its fields and geometry fields.
    1710             :  *
    1711             :  * This method should only be called by driver implementations.
    1712             :  *
    1713             :  * @param bSealFields Whether fields and geometry fields should be sealed.
    1714             :  *                    This is generally desirabled, but in case of deferred
    1715             :  *                    resolution of them, this parameter should be set to false.
    1716             :  * @since GDAL 3.9
    1717             :  */
    1718       49829 : void OGRFeatureDefn::Seal(bool bSealFields)
    1719             : {
    1720       49829 :     if (m_bSealed)
    1721             :     {
    1722           1 :         CPLError(CE_Failure, CPLE_AppDefined,
    1723             :                  "OGRFeatureDefn::Seal(): the object is already sealed");
    1724           1 :         return;
    1725             :     }
    1726       49828 :     if (bSealFields)
    1727             :     {
    1728       38274 :         const int nFieldCount = GetFieldCount();
    1729     4747970 :         for (int i = 0; i < nFieldCount; ++i)
    1730     4709700 :             GetFieldDefn(i)->Seal();
    1731       38274 :         const int nGeomFieldCount = GetGeomFieldCount();
    1732       66418 :         for (int i = 0; i < nGeomFieldCount; ++i)
    1733       28144 :             GetGeomFieldDefn(i)->Seal();
    1734             :     }
    1735       49828 :     m_bSealed = true;
    1736             : }
    1737             : 
    1738             : /************************************************************************/
    1739             : /*                       OGRFeatureDefn::Unseal()                       */
    1740             : /************************************************************************/
    1741             : 
    1742             : /** Unseal a OGRFeatureDefn.
    1743             :  *
    1744             :  * Undo OGRFeatureDefn::Seal()
    1745             :  *
    1746             :  * This method also call OGRFieldDefn::Unseal() and OGRGeomFieldDefn::Unseal()
    1747             :  * on its fields and geometry fields.
    1748             :  *
    1749             :  * Using GetTemporaryUnsealer() is recommended for most use cases.
    1750             :  *
    1751             :  * This method should only be called by driver implementations.
    1752             :  *
    1753             :  * @param bUnsealFields Whether fields and geometry fields should be unsealed.
    1754             :  *                      This is generally desirabled, but in case of deferred
    1755             :  *                      resolution of them, this parameter should be set to
    1756             :  * false.
    1757             :  * @since GDAL 3.9
    1758             :  */
    1759       25539 : void OGRFeatureDefn::Unseal(bool bUnsealFields)
    1760             : {
    1761       25539 :     if (!m_bSealed)
    1762             :     {
    1763           1 :         CPLError(CE_Failure, CPLE_AppDefined,
    1764             :                  "OGRFeatureDefn::Unseal(): the object is already unsealed");
    1765           1 :         return;
    1766             :     }
    1767       25538 :     m_bSealed = false;
    1768       25538 :     if (bUnsealFields)
    1769             :     {
    1770       25491 :         const int nFieldCount = GetFieldCount();
    1771     4697750 :         for (int i = 0; i < nFieldCount; ++i)
    1772     4672260 :             GetFieldDefn(i)->Unseal();
    1773       25491 :         const int nGeomFieldCount = GetGeomFieldCount();
    1774       42276 :         for (int i = 0; i < nGeomFieldCount; ++i)
    1775       16785 :             GetGeomFieldDefn(i)->Unseal();
    1776             :     }
    1777             : }
    1778             : 
    1779             : /************************************************************************/
    1780             : /*                  OGRFeatureDefn::GetTemporaryUnsealer()              */
    1781             : /************************************************************************/
    1782             : 
    1783             : /** Return an object that temporary unseals the OGRFeatureDefn
    1784             :  *
    1785             :  * The returned object calls Unseal() initially, and when it is destroyed
    1786             :  * it calls Seal().
    1787             :  * This method should be called on a OGRFeatureDefn that has been sealed
    1788             :  * previously.
    1789             :  * GetTemporaryUnsealer() calls may be nested, in which case only the first
    1790             :  * one has an effect (similarly to a recursive mutex locked in a nested way
    1791             :  * from the same thread).
    1792             :  *
    1793             :  * This method should only be called by driver implementations.
    1794             :  *
    1795             :  * It is also possible to use the helper method whileUnsealing(). Example:
    1796             :  * whileUnsealing(poFeatureDefn)->some_method()
    1797             :  *
    1798             :  * @param bSealFields Whether fields and geometry fields should be unsealed and
    1799             :  *                    resealed.
    1800             :  *                    This is generally desirabled, but in case of deferred
    1801             :  *                    resolution of them, this parameter should be set to false.
    1802             :  * @since GDAL 3.9
    1803             :  */
    1804             : OGRFeatureDefn::TemporaryUnsealer
    1805       25563 : OGRFeatureDefn::GetTemporaryUnsealer(bool bSealFields)
    1806             : {
    1807       25563 :     return TemporaryUnsealer(this, bSealFields);
    1808             : }
    1809             : 
    1810             : /*! @cond Doxygen_Suppress */
    1811             : 
    1812             : /************************************************************************/
    1813             : /*                TemporaryUnsealer::TemporaryUnsealer()                */
    1814             : /************************************************************************/
    1815             : 
    1816       25563 : OGRFeatureDefn::TemporaryUnsealer::TemporaryUnsealer(
    1817       25563 :     OGRFeatureDefn *poFeatureDefn, bool bSealFields)
    1818       25563 :     : m_poFeatureDefn(poFeatureDefn), m_bSealFields(bSealFields)
    1819             : {
    1820       25563 :     if (m_poFeatureDefn->m_nTemporaryUnsealCount == 0)
    1821             :     {
    1822       25561 :         if (m_poFeatureDefn->m_bSealed)
    1823             :         {
    1824       25538 :             m_poFeatureDefn->Unseal(m_bSealFields);
    1825       25538 :             m_poFeatureDefn->m_nTemporaryUnsealCount = 1;
    1826             :         }
    1827             :         else
    1828             :         {
    1829          23 :             CPLError(CE_Warning, CPLE_AppDefined,
    1830             :                      "OGRFeatureDefn::GetTemporaryUnsealer() called on "
    1831             :                      "a unsealed object");
    1832          23 :             m_poFeatureDefn->m_nTemporaryUnsealCount = -1;
    1833             :         }
    1834             :     }
    1835           2 :     else if (m_poFeatureDefn->m_nTemporaryUnsealCount > 0)
    1836             :     {
    1837             :         // m_poFeatureDefn is already under an active TemporaryUnsealer.
    1838             :         // Just increment the counter
    1839           1 :         ++m_poFeatureDefn->m_nTemporaryUnsealCount;
    1840             :     }
    1841             :     else
    1842             :     {
    1843             :         // m_poFeatureDefn is already under a misused TemporaryUnsealer.
    1844             :         // Decrement again the counter
    1845           1 :         --m_poFeatureDefn->m_nTemporaryUnsealCount;
    1846             :     }
    1847       25563 : }
    1848             : 
    1849             : /************************************************************************/
    1850             : /*                TemporaryUnsealer::~TemporaryUnsealer()               */
    1851             : /************************************************************************/
    1852             : 
    1853       51126 : OGRFeatureDefn::TemporaryUnsealer::~TemporaryUnsealer()
    1854             : {
    1855       25563 :     if (m_poFeatureDefn->m_nTemporaryUnsealCount > 0)
    1856             :     {
    1857             :         // m_poFeatureDefn is already under an active TemporaryUnsealer.
    1858             :         // Decrement increment the counter and unseal when it reaches 0
    1859       25539 :         --m_poFeatureDefn->m_nTemporaryUnsealCount;
    1860       25539 :         if (m_poFeatureDefn->m_nTemporaryUnsealCount == 0)
    1861             :         {
    1862       25538 :             if (!m_poFeatureDefn->m_bSealed)
    1863             :             {
    1864       25538 :                 m_poFeatureDefn->Seal(m_bSealFields);
    1865             :             }
    1866             :             else
    1867             :             {
    1868           0 :                 CPLError(
    1869             :                     CE_Failure, CPLE_AppDefined,
    1870             :                     "Misuse of sealing functionality. "
    1871             :                     "OGRFeatureDefn::TemporaryUnsealer::~TemporaryUnsealer() "
    1872             :                     "claled on a sealed object");
    1873             :             }
    1874             :         }
    1875             :     }
    1876             :     else
    1877             :     {
    1878             :         // m_poFeatureDefn is already under a misused TemporaryUnsealer.
    1879             :         // Increment the counter
    1880          24 :         CPLAssert(m_poFeatureDefn->m_nTemporaryUnsealCount < 0);
    1881          24 :         ++m_poFeatureDefn->m_nTemporaryUnsealCount;
    1882             :     }
    1883       25563 : }
    1884             : 
    1885             : /*! @endcond */

Generated by: LCOV version 1.14