LCOV - code coverage report
Current view: top level - ogr - ogrfeaturedefn.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 327 356 91.9 %
Date: 2024-05-03 15:49:35 Functions: 56 61 91.8 %

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

Generated by: LCOV version 1.14