LCOV - code coverage report
Current view: top level - ogr - ogrfeaturedefn.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 334 376 88.8 %
Date: 2025-10-21 22:35:35 Functions: 57 64 89.1 %

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

Generated by: LCOV version 1.14