LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/mem - ogrmemlayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 402 453 88.7 %
Date: 2024-11-21 22:18:42 Functions: 27 28 96.4 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implements OGRMemLayer class.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2003, Frank Warmerdam <warmerdam@pobox.com>
       9             :  * Copyright (c) 2009-2013, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "cpl_port.h"
      15             : #include "ogr_mem.h"
      16             : 
      17             : #include <cstddef>
      18             : #include <cstring>
      19             : #include <algorithm>
      20             : #include <map>
      21             : #include <new>
      22             : #include <utility>
      23             : 
      24             : #include "cpl_conv.h"
      25             : #include "cpl_error.h"
      26             : #include "cpl_vsi.h"
      27             : #include "ogr_api.h"
      28             : #include "ogr_core.h"
      29             : #include "ogr_feature.h"
      30             : #include "ogr_geometry.h"
      31             : #include "ogr_p.h"
      32             : #include "ogr_spatialref.h"
      33             : #include "ogrsf_frmts.h"
      34             : 
      35             : /************************************************************************/
      36             : /*                      IOGRMemLayerFeatureIterator                     */
      37             : /************************************************************************/
      38             : 
      39             : class IOGRMemLayerFeatureIterator
      40             : {
      41             :   public:
      42         428 :     virtual ~IOGRMemLayerFeatureIterator()
      43         428 :     {
      44         428 :     }
      45             : 
      46             :     virtual OGRFeature *Next() = 0;
      47             : };
      48             : 
      49             : /************************************************************************/
      50             : /*                            OGRMemLayer()                             */
      51             : /************************************************************************/
      52             : 
      53        3370 : OGRMemLayer::OGRMemLayer(const char *pszName,
      54             :                          const OGRSpatialReference *poSRSIn,
      55        3370 :                          OGRwkbGeometryType eReqType)
      56        3370 :     : m_poFeatureDefn(new OGRFeatureDefn(pszName))
      57             : {
      58        3370 :     m_poFeatureDefn->Reference();
      59             : 
      60        3370 :     SetDescription(m_poFeatureDefn->GetName());
      61        3370 :     m_poFeatureDefn->SetGeomType(eReqType);
      62             : 
      63        3370 :     if (eReqType != wkbNone && poSRSIn != nullptr)
      64             :     {
      65         426 :         OGRSpatialReference *poSRS = poSRSIn->Clone();
      66         426 :         m_poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);
      67         426 :         poSRS->Release();
      68             :     }
      69             : 
      70        3370 :     m_oMapFeaturesIter = m_oMapFeatures.begin();
      71        3370 :     m_poFeatureDefn->Seal(/* bSealFields = */ true);
      72        3370 : }
      73             : 
      74             : /************************************************************************/
      75             : /*                           ~OGRMemLayer()                           */
      76             : /************************************************************************/
      77             : 
      78        5575 : OGRMemLayer::~OGRMemLayer()
      79             : 
      80             : {
      81        3369 :     if (m_nFeaturesRead > 0 && m_poFeatureDefn != nullptr)
      82             :     {
      83        1350 :         CPLDebug("Mem", CPL_FRMT_GIB " features read on layer '%s'.",
      84        1350 :                  m_nFeaturesRead, m_poFeatureDefn->GetName());
      85             :     }
      86             : 
      87        3369 :     if (m_papoFeatures != nullptr)
      88             :     {
      89      702163 :         for (GIntBig i = 0; i < m_nMaxFeatureCount; i++)
      90             :         {
      91      699990 :             if (m_papoFeatures[i] != nullptr)
      92      576738 :                 delete m_papoFeatures[i];
      93             :         }
      94        2173 :         CPLFree(m_papoFeatures);
      95             :     }
      96             : 
      97        3369 :     if (m_poFeatureDefn)
      98        3369 :         m_poFeatureDefn->Release();
      99        5575 : }
     100             : 
     101             : /************************************************************************/
     102             : /*                            ResetReading()                            */
     103             : /************************************************************************/
     104             : 
     105        6180 : void OGRMemLayer::ResetReading()
     106             : 
     107             : {
     108        6180 :     m_iNextReadFID = 0;
     109        6180 :     m_oMapFeaturesIter = m_oMapFeatures.begin();
     110        6180 : }
     111             : 
     112             : /************************************************************************/
     113             : /*                           GetNextFeature()                           */
     114             : /************************************************************************/
     115             : 
     116       50509 : OGRFeature *OGRMemLayer::GetNextFeature()
     117             : 
     118             : {
     119             :     while (true)
     120             :     {
     121       50509 :         OGRFeature *poFeature = nullptr;
     122       50509 :         if (m_papoFeatures)
     123             :         {
     124       50339 :             if (m_iNextReadFID >= m_nMaxFeatureCount)
     125        1972 :                 return nullptr;
     126       48367 :             poFeature = m_papoFeatures[m_iNextReadFID++];
     127       48367 :             if (poFeature == nullptr)
     128       29633 :                 continue;
     129             :         }
     130         170 :         else if (m_oMapFeaturesIter != m_oMapFeatures.end())
     131             :         {
     132          21 :             poFeature = m_oMapFeaturesIter->second.get();
     133          21 :             ++m_oMapFeaturesIter;
     134             :         }
     135             :         else
     136             :         {
     137         149 :             break;
     138             :         }
     139             : 
     140       40640 :         if ((m_poFilterGeom == nullptr ||
     141       35238 :              FilterGeometry(poFeature->GetGeomFieldRef(m_iGeomFieldFilter))) &&
     142       16483 :             (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poFeature)))
     143             :         {
     144       15517 :             m_nFeaturesRead++;
     145       15517 :             return poFeature->Clone();
     146             :         }
     147       32871 :     }
     148             : 
     149         149 :     return nullptr;
     150             : }
     151             : 
     152             : /************************************************************************/
     153             : /*                           SetNextByIndex()                           */
     154             : /************************************************************************/
     155             : 
     156         358 : OGRErr OGRMemLayer::SetNextByIndex(GIntBig nIndex)
     157             : 
     158             : {
     159         358 :     if (m_poFilterGeom != nullptr || m_poAttrQuery != nullptr ||
     160         357 :         m_papoFeatures == nullptr || m_bHasHoles)
     161          32 :         return OGRLayer::SetNextByIndex(nIndex);
     162             : 
     163         326 :     if (nIndex < 0 || nIndex >= m_nMaxFeatureCount)
     164          34 :         return OGRERR_FAILURE;
     165             : 
     166         292 :     m_iNextReadFID = nIndex;
     167             : 
     168         292 :     return OGRERR_NONE;
     169             : }
     170             : 
     171             : /************************************************************************/
     172             : /*                         GetFeatureRef()                              */
     173             : /************************************************************************/
     174             : 
     175        3877 : OGRFeature *OGRMemLayer::GetFeatureRef(GIntBig nFeatureId)
     176             : 
     177             : {
     178        3877 :     if (nFeatureId < 0)
     179          26 :         return nullptr;
     180             : 
     181        3851 :     OGRFeature *poFeature = nullptr;
     182        3851 :     if (m_papoFeatures != nullptr)
     183             :     {
     184        3623 :         if (nFeatureId >= m_nMaxFeatureCount)
     185          53 :             return nullptr;
     186        3570 :         poFeature = m_papoFeatures[nFeatureId];
     187             :     }
     188             :     else
     189             :     {
     190         228 :         FeatureIterator oIter = m_oMapFeatures.find(nFeatureId);
     191         228 :         if (oIter != m_oMapFeatures.end())
     192           3 :             poFeature = oIter->second.get();
     193             :     }
     194             : 
     195        3798 :     return poFeature;
     196             : }
     197             : 
     198             : /************************************************************************/
     199             : /*                             GetFeature()                             */
     200             : /************************************************************************/
     201             : 
     202        3849 : OGRFeature *OGRMemLayer::GetFeature(GIntBig nFeatureId)
     203             : 
     204             : {
     205        3849 :     const OGRFeature *poFeature = GetFeatureRef(nFeatureId);
     206        3849 :     return poFeature ? poFeature->Clone() : nullptr;
     207             : }
     208             : 
     209             : /************************************************************************/
     210             : /*                             ISetFeature()                             */
     211             : /************************************************************************/
     212             : 
     213      577112 : OGRErr OGRMemLayer::ISetFeature(OGRFeature *poFeature)
     214             : 
     215             : {
     216      577112 :     if (!m_bUpdatable)
     217           0 :         return OGRERR_FAILURE;
     218             : 
     219      577112 :     if (poFeature == nullptr)
     220           0 :         return OGRERR_FAILURE;
     221             : 
     222             :     // If we don't have a FID, find one available
     223      577112 :     GIntBig nFID = poFeature->GetFID();
     224      577112 :     if (nFID == OGRNullFID)
     225             :     {
     226      576219 :         if (m_papoFeatures != nullptr)
     227             :         {
     228      574404 :             while (m_iNextCreateFID < m_nMaxFeatureCount &&
     229      571947 :                    m_papoFeatures[m_iNextCreateFID] != nullptr)
     230             :             {
     231           1 :                 m_iNextCreateFID++;
     232             :             }
     233             :         }
     234             :         else
     235             :         {
     236        1816 :             FeatureIterator oIter;
     237        1816 :             while ((oIter = m_oMapFeatures.find(m_iNextCreateFID)) !=
     238        3632 :                    m_oMapFeatures.end())
     239           0 :                 ++m_iNextCreateFID;
     240             :         }
     241      576219 :         nFID = m_iNextCreateFID++;
     242      576219 :         poFeature->SetFID(nFID);
     243             :     }
     244         893 :     else if (nFID < OGRNullFID)
     245             :     {
     246          11 :         CPLError(CE_Failure, CPLE_NotSupported,
     247             :                  "negative FID are not supported");
     248          11 :         return OGRERR_FAILURE;
     249             :     }
     250             :     else
     251             :     {
     252         882 :         if (!m_bHasHoles)
     253             :         {
     254             :             // If the feature does not exist, set m_bHasHoles
     255         507 :             if (m_papoFeatures != nullptr)
     256             :             {
     257         265 :                 if (nFID >= m_nMaxFeatureCount ||
     258         265 :                     m_papoFeatures[nFID] == nullptr)
     259             :                 {
     260           3 :                     m_bHasHoles = true;
     261             :                 }
     262             :             }
     263             :             else
     264             :             {
     265         242 :                 FeatureIterator oIter = m_oMapFeatures.find(nFID);
     266         242 :                 if (oIter == m_oMapFeatures.end())
     267         242 :                     m_bHasHoles = true;
     268             :             }
     269             :         }
     270             :     }
     271             : 
     272     1154200 :     auto poFeatureCloned = std::unique_ptr<OGRFeature>(poFeature->Clone());
     273      577101 :     if (poFeatureCloned == nullptr)
     274           0 :         return OGRERR_FAILURE;
     275             : 
     276      577101 :     if (m_papoFeatures != nullptr && nFID > 100000 &&
     277      106751 :         nFID > m_nMaxFeatureCount + 1000)
     278             :     {
     279             :         // Convert to map if gap from current max size is too big.
     280             :         auto poIter =
     281           2 :             std::unique_ptr<IOGRMemLayerFeatureIterator>(GetIterator());
     282             :         try
     283             :         {
     284           2 :             OGRFeature *poFeatureIter = nullptr;
     285           5 :             while ((poFeatureIter = poIter->Next()) != nullptr)
     286             :             {
     287           3 :                 m_oMapFeatures[poFeatureIter->GetFID()] =
     288           6 :                     std::unique_ptr<OGRFeature>(poFeatureIter);
     289             :             }
     290           2 :             CPLFree(m_papoFeatures);
     291           2 :             m_papoFeatures = nullptr;
     292           2 :             m_nMaxFeatureCount = 0;
     293             :         }
     294           0 :         catch (const std::bad_alloc &)
     295             :         {
     296           0 :             m_oMapFeatures.clear();
     297           0 :             m_oMapFeaturesIter = m_oMapFeatures.end();
     298           0 :             CPLError(CE_Failure, CPLE_OutOfMemory, "Cannot allocate memory");
     299           0 :             return OGRERR_FAILURE;
     300             :         }
     301             :     }
     302             : 
     303      901407 :     for (int i = 0; i < m_poFeatureDefn->GetGeomFieldCount(); ++i)
     304             :     {
     305      324306 :         OGRGeometry *poGeom = poFeatureCloned->GetGeomFieldRef(i);
     306      324306 :         if (poGeom != nullptr && poGeom->getSpatialReference() == nullptr)
     307             :         {
     308        2986 :             poGeom->assignSpatialReference(
     309        2986 :                 m_poFeatureDefn->GetGeomFieldDefn(i)->GetSpatialRef());
     310             :         }
     311             :     }
     312             : 
     313      577101 :     if (m_papoFeatures != nullptr || (m_oMapFeatures.empty() && nFID <= 100000))
     314             :     {
     315      577092 :         if (nFID >= m_nMaxFeatureCount)
     316             :         {
     317             :             const GIntBig nNewCount = std::max(
     318        4645 :                 m_nMaxFeatureCount + m_nMaxFeatureCount / 3 + 10, nFID + 1);
     319        4645 :             if (static_cast<GIntBig>(static_cast<size_t>(sizeof(OGRFeature *)) *
     320        4645 :                                      nNewCount) !=
     321        4645 :                 static_cast<GIntBig>(sizeof(OGRFeature *)) * nNewCount)
     322             :             {
     323           0 :                 CPLError(CE_Failure, CPLE_OutOfMemory,
     324             :                          "Cannot allocate array of " CPL_FRMT_GIB " elements",
     325             :                          nNewCount);
     326           0 :                 return OGRERR_FAILURE;
     327             :             }
     328             : 
     329             :             OGRFeature **papoNewFeatures =
     330        4645 :                 static_cast<OGRFeature **>(VSI_REALLOC_VERBOSE(
     331             :                     m_papoFeatures,
     332             :                     static_cast<size_t>(sizeof(OGRFeature *) * nNewCount)));
     333        4645 :             if (papoNewFeatures == nullptr)
     334             :             {
     335           0 :                 return OGRERR_FAILURE;
     336             :             }
     337        4645 :             m_papoFeatures = papoNewFeatures;
     338        4645 :             memset(m_papoFeatures + m_nMaxFeatureCount, 0,
     339             :                    sizeof(OGRFeature *) *
     340        4645 :                        static_cast<size_t>(nNewCount - m_nMaxFeatureCount));
     341        4645 :             m_nMaxFeatureCount = nNewCount;
     342             :         }
     343             : #ifdef DEBUG
     344             :         // Just to please Coverity. Cannot happen.
     345      577092 :         if (m_papoFeatures == nullptr)
     346             :         {
     347           0 :             return OGRERR_FAILURE;
     348             :         }
     349             : #endif
     350             : 
     351      577092 :         if (m_papoFeatures[nFID] != nullptr)
     352             :         {
     353         317 :             delete m_papoFeatures[nFID];
     354         317 :             m_papoFeatures[nFID] = nullptr;
     355             :         }
     356             :         else
     357             :         {
     358      576775 :             ++m_nFeatureCount;
     359             :         }
     360             : 
     361      577092 :         m_papoFeatures[nFID] = poFeatureCloned.release();
     362             :     }
     363             :     else
     364             :     {
     365           9 :         FeatureIterator oIter = m_oMapFeatures.find(nFID);
     366           9 :         if (oIter != m_oMapFeatures.end())
     367             :         {
     368           1 :             oIter->second = std::move(poFeatureCloned);
     369             :         }
     370             :         else
     371             :         {
     372             :             try
     373             :             {
     374           8 :                 m_oMapFeatures[nFID] = std::move(poFeatureCloned);
     375           8 :                 m_oMapFeaturesIter = m_oMapFeatures.end();
     376           8 :                 m_nFeatureCount++;
     377             :             }
     378           0 :             catch (const std::bad_alloc &)
     379             :             {
     380           0 :                 CPLError(CE_Failure, CPLE_OutOfMemory,
     381             :                          "Cannot allocate memory");
     382           0 :                 return OGRERR_FAILURE;
     383             :             }
     384             :         }
     385             :     }
     386             : 
     387      577101 :     m_bUpdated = true;
     388             : 
     389      577101 :     return OGRERR_NONE;
     390             : }
     391             : 
     392             : /************************************************************************/
     393             : /*                           ICreateFeature()                            */
     394             : /************************************************************************/
     395             : 
     396      576404 : OGRErr OGRMemLayer::ICreateFeature(OGRFeature *poFeature)
     397             : 
     398             : {
     399      576404 :     if (!m_bUpdatable)
     400           0 :         return OGRERR_FAILURE;
     401             : 
     402      576596 :     if (poFeature->GetFID() != OGRNullFID &&
     403         192 :         poFeature->GetFID() != m_iNextCreateFID)
     404         179 :         m_bHasHoles = true;
     405             : 
     406             :     // If the feature has already a FID and that a feature with the same
     407             :     // FID is already registered in the layer, then unset our FID.
     408      576404 :     if (poFeature->GetFID() >= 0)
     409             :     {
     410         191 :         if (m_papoFeatures != nullptr)
     411             :         {
     412         100 :             if (poFeature->GetFID() < m_nMaxFeatureCount &&
     413          46 :                 m_papoFeatures[poFeature->GetFID()] != nullptr)
     414             :             {
     415           6 :                 poFeature->SetFID(OGRNullFID);
     416             :             }
     417             :         }
     418             :         else
     419             :         {
     420         137 :             FeatureIterator oIter = m_oMapFeatures.find(poFeature->GetFID());
     421         137 :             if (oIter != m_oMapFeatures.end())
     422           1 :                 poFeature->SetFID(OGRNullFID);
     423             :         }
     424             :     }
     425             : 
     426             :     // Prevent calling ISetFeature() from derived classes
     427      576404 :     return OGRMemLayer::ISetFeature(poFeature);
     428             : }
     429             : 
     430             : /************************************************************************/
     431             : /*                           UpsertFeature()                            */
     432             : /************************************************************************/
     433             : 
     434           2 : OGRErr OGRMemLayer::IUpsertFeature(OGRFeature *poFeature)
     435             : 
     436             : {
     437           2 :     if (!TestCapability(OLCUpsertFeature))
     438           0 :         return OGRERR_FAILURE;
     439             : 
     440           2 :     if (GetFeatureRef(poFeature->GetFID()))
     441             :     {
     442           1 :         return ISetFeature(poFeature);
     443             :     }
     444             :     else
     445             :     {
     446           1 :         return ICreateFeature(poFeature);
     447             :     }
     448             : }
     449             : 
     450             : /************************************************************************/
     451             : /*                           UpdateFeature()                            */
     452             : /************************************************************************/
     453             : 
     454          14 : OGRErr OGRMemLayer::IUpdateFeature(OGRFeature *poFeature,
     455             :                                    int nUpdatedFieldsCount,
     456             :                                    const int *panUpdatedFieldsIdx,
     457             :                                    int nUpdatedGeomFieldsCount,
     458             :                                    const int *panUpdatedGeomFieldsIdx,
     459             :                                    bool bUpdateStyleString)
     460             : 
     461             : {
     462          14 :     if (!TestCapability(OLCUpdateFeature))
     463           0 :         return OGRERR_FAILURE;
     464             : 
     465          14 :     auto poFeatureRef = GetFeatureRef(poFeature->GetFID());
     466          14 :     if (!poFeatureRef)
     467           2 :         return OGRERR_NON_EXISTING_FEATURE;
     468             : 
     469          24 :     for (int i = 0; i < nUpdatedFieldsCount; ++i)
     470             :     {
     471          12 :         poFeatureRef->SetField(
     472          12 :             panUpdatedFieldsIdx[i],
     473          12 :             poFeature->GetRawFieldRef(panUpdatedFieldsIdx[i]));
     474             :     }
     475          12 :     for (int i = 0; i < nUpdatedGeomFieldsCount; ++i)
     476             :     {
     477           0 :         poFeatureRef->SetGeomFieldDirectly(
     478           0 :             panUpdatedGeomFieldsIdx[i],
     479           0 :             poFeature->StealGeometry(panUpdatedGeomFieldsIdx[i]));
     480             :     }
     481          12 :     if (bUpdateStyleString)
     482             :     {
     483           0 :         poFeatureRef->SetStyleString(poFeature->GetStyleString());
     484             :     }
     485             : 
     486          12 :     m_bUpdated = true;
     487             : 
     488          12 :     return OGRERR_NONE;
     489             : }
     490             : 
     491             : /************************************************************************/
     492             : /*                           DeleteFeature()                            */
     493             : /************************************************************************/
     494             : 
     495          82 : OGRErr OGRMemLayer::DeleteFeature(GIntBig nFID)
     496             : 
     497             : {
     498          82 :     if (!m_bUpdatable)
     499          32 :         return OGRERR_FAILURE;
     500             : 
     501          50 :     if (nFID < 0)
     502             :     {
     503           7 :         return OGRERR_FAILURE;
     504             :     }
     505             : 
     506          43 :     if (m_papoFeatures != nullptr)
     507             :     {
     508          41 :         if (nFID >= m_nMaxFeatureCount || m_papoFeatures[nFID] == nullptr)
     509             :         {
     510           8 :             return OGRERR_FAILURE;
     511             :         }
     512          33 :         delete m_papoFeatures[nFID];
     513          33 :         m_papoFeatures[nFID] = nullptr;
     514             :     }
     515             :     else
     516             :     {
     517           2 :         FeatureIterator oIter = m_oMapFeatures.find(nFID);
     518           2 :         if (oIter == m_oMapFeatures.end())
     519             :         {
     520           1 :             return OGRERR_FAILURE;
     521             :         }
     522           1 :         m_oMapFeatures.erase(oIter);
     523             :     }
     524             : 
     525          34 :     m_bHasHoles = true;
     526          34 :     --m_nFeatureCount;
     527             : 
     528          34 :     m_bUpdated = true;
     529             : 
     530          34 :     return OGRERR_NONE;
     531             : }
     532             : 
     533             : /************************************************************************/
     534             : /*                          GetFeatureCount()                           */
     535             : /*                                                                      */
     536             : /*      If a spatial filter is in effect, we turn control over to       */
     537             : /*      the generic counter.  Otherwise we return the total count.      */
     538             : /*      Eventually we should consider implementing a more efficient     */
     539             : /*      way of counting features matching a spatial query.              */
     540             : /************************************************************************/
     541             : 
     542        1542 : GIntBig OGRMemLayer::GetFeatureCount(int bForce)
     543             : 
     544             : {
     545        1542 :     if (m_poFilterGeom != nullptr || m_poAttrQuery != nullptr)
     546         190 :         return OGRLayer::GetFeatureCount(bForce);
     547             : 
     548        1352 :     return m_nFeatureCount;
     549             : }
     550             : 
     551             : /************************************************************************/
     552             : /*                           TestCapability()                           */
     553             : /************************************************************************/
     554             : 
     555        6575 : int OGRMemLayer::TestCapability(const char *pszCap)
     556             : 
     557             : {
     558        6575 :     if (EQUAL(pszCap, OLCRandomRead))
     559          13 :         return TRUE;
     560             : 
     561        6562 :     else if (EQUAL(pszCap, OLCSequentialWrite) || EQUAL(pszCap, OLCRandomWrite))
     562         121 :         return m_bUpdatable;
     563             : 
     564        6441 :     else if (EQUAL(pszCap, OLCFastFeatureCount))
     565         323 :         return m_poFilterGeom == nullptr && m_poAttrQuery == nullptr;
     566             : 
     567        6118 :     else if (EQUAL(pszCap, OLCFastSpatialFilter))
     568           1 :         return FALSE;
     569             : 
     570        6117 :     else if (EQUAL(pszCap, OLCDeleteFeature) ||
     571        6092 :              EQUAL(pszCap, OLCUpsertFeature) || EQUAL(pszCap, OLCUpdateFeature))
     572          43 :         return m_bUpdatable;
     573             : 
     574        6074 :     else if (EQUAL(pszCap, OLCCreateField) ||
     575        5993 :              EQUAL(pszCap, OLCCreateGeomField) ||
     576        5992 :              EQUAL(pszCap, OLCDeleteField) || EQUAL(pszCap, OLCReorderFields) ||
     577        5936 :              EQUAL(pszCap, OLCAlterFieldDefn) ||
     578        5908 :              EQUAL(pszCap, OLCAlterGeomFieldDefn))
     579         167 :         return m_bUpdatable;
     580             : 
     581        5907 :     else if (EQUAL(pszCap, OLCFastSetNextByIndex))
     582           3 :         return m_poFilterGeom == nullptr && m_poAttrQuery == nullptr &&
     583           1 :                ((m_papoFeatures != nullptr && !m_bHasHoles) ||
     584           2 :                 m_oMapFeatures.empty());
     585             : 
     586        5905 :     else if (EQUAL(pszCap, OLCStringsAsUTF8))
     587         994 :         return m_bAdvertizeUTF8;
     588             : 
     589        4911 :     else if (EQUAL(pszCap, OLCCurveGeometries))
     590        2194 :         return TRUE;
     591             : 
     592        2717 :     else if (EQUAL(pszCap, OLCMeasuredGeometries))
     593        2207 :         return TRUE;
     594             : 
     595         510 :     else if (EQUAL(pszCap, OLCZGeometries))
     596          66 :         return TRUE;
     597             : 
     598         444 :     return FALSE;
     599             : }
     600             : 
     601             : /************************************************************************/
     602             : /*                            CreateField()                             */
     603             : /************************************************************************/
     604             : 
     605       11335 : OGRErr OGRMemLayer::CreateField(const OGRFieldDefn *poField,
     606             :                                 int /* bApproxOK */)
     607             : {
     608       11335 :     if (!m_bUpdatable)
     609           0 :         return OGRERR_FAILURE;
     610             : 
     611             :     // Simple case, no features exist yet.
     612       11335 :     if (m_nFeatureCount == 0)
     613             :     {
     614       10974 :         whileUnsealing(m_poFeatureDefn)->AddFieldDefn(poField);
     615       10974 :         return OGRERR_NONE;
     616             :     }
     617             : 
     618             :     // Add field definition and setup remap definition.
     619             :     {
     620         361 :         whileUnsealing(m_poFeatureDefn)->AddFieldDefn(poField);
     621             :     }
     622             : 
     623             :     // Remap all the internal features.  Hopefully there aren't any
     624             :     // external features referring to our OGRFeatureDefn!
     625         361 :     auto poIter = std::unique_ptr<IOGRMemLayerFeatureIterator>(GetIterator());
     626         361 :     OGRFeature *poFeature = nullptr;
     627         936 :     while ((poFeature = poIter->Next()) != nullptr)
     628             :     {
     629         575 :         poFeature->AppendField();
     630             :     }
     631             : 
     632         361 :     m_bUpdated = true;
     633             : 
     634         361 :     return OGRERR_NONE;
     635             : }
     636             : 
     637             : /************************************************************************/
     638             : /*                            DeleteField()                             */
     639             : /************************************************************************/
     640             : 
     641          13 : OGRErr OGRMemLayer::DeleteField(int iField)
     642             : {
     643          13 :     if (!m_bUpdatable)
     644           0 :         return OGRERR_FAILURE;
     645             : 
     646          13 :     if (iField < 0 || iField >= m_poFeatureDefn->GetFieldCount())
     647             :     {
     648           3 :         CPLError(CE_Failure, CPLE_NotSupported, "Invalid field index");
     649           3 :         return OGRERR_FAILURE;
     650             :     }
     651             : 
     652             :     // Update all the internal features.  Hopefully there aren't any
     653             :     // external features referring to our OGRFeatureDefn!
     654          10 :     auto poIter = std::unique_ptr<IOGRMemLayerFeatureIterator>(GetIterator());
     655          26 :     while (OGRFeature *poFeature = poIter->Next())
     656             :     {
     657          16 :         OGRField *poFieldRaw = poFeature->GetRawFieldRef(iField);
     658          23 :         if (poFeature->IsFieldSetAndNotNull(iField) &&
     659           7 :             !poFeature->IsFieldNull(iField))
     660             :         {
     661             :             // Little trick to unallocate the field.
     662             :             OGRField sField;
     663           7 :             OGR_RawField_SetUnset(&sField);
     664           7 :             poFeature->SetField(iField, &sField);
     665             :         }
     666             : 
     667          16 :         if (iField < m_poFeatureDefn->GetFieldCount() - 1)
     668             :         {
     669           6 :             memmove(poFieldRaw, poFieldRaw + 1,
     670             :                     sizeof(OGRField) *
     671           6 :                         (m_poFeatureDefn->GetFieldCount() - 1 - iField));
     672             :         }
     673          16 :     }
     674             : 
     675          10 :     m_bUpdated = true;
     676             : 
     677          10 :     return whileUnsealing(m_poFeatureDefn)->DeleteFieldDefn(iField);
     678             : }
     679             : 
     680             : /************************************************************************/
     681             : /*                           ReorderFields()                            */
     682             : /************************************************************************/
     683             : 
     684          17 : OGRErr OGRMemLayer::ReorderFields(int *panMap)
     685             : {
     686          17 :     if (!m_bUpdatable)
     687           0 :         return OGRERR_FAILURE;
     688             : 
     689          17 :     if (m_poFeatureDefn->GetFieldCount() == 0)
     690           4 :         return OGRERR_NONE;
     691             : 
     692             :     const OGRErr eErr =
     693          13 :         OGRCheckPermutation(panMap, m_poFeatureDefn->GetFieldCount());
     694          13 :     if (eErr != OGRERR_NONE)
     695           2 :         return eErr;
     696             : 
     697             :     // Remap all the internal features.  Hopefully there aren't any
     698             :     // external features referring to our OGRFeatureDefn!
     699          11 :     auto poIter = std::unique_ptr<IOGRMemLayerFeatureIterator>(GetIterator());
     700          49 :     while (OGRFeature *poFeature = poIter->Next())
     701             :     {
     702          38 :         poFeature->RemapFields(nullptr, panMap);
     703          38 :     }
     704             : 
     705          11 :     m_bUpdated = true;
     706             : 
     707          11 :     return whileUnsealing(m_poFeatureDefn)->ReorderFieldDefns(panMap);
     708             : }
     709             : 
     710             : /************************************************************************/
     711             : /*                           AlterFieldDefn()                           */
     712             : /************************************************************************/
     713             : 
     714          64 : OGRErr OGRMemLayer::AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
     715             :                                    int nFlagsIn)
     716             : {
     717          64 :     if (!m_bUpdatable)
     718           0 :         return OGRERR_FAILURE;
     719             : 
     720          64 :     if (iField < 0 || iField >= m_poFeatureDefn->GetFieldCount())
     721             :     {
     722           3 :         CPLError(CE_Failure, CPLE_NotSupported, "Invalid field index");
     723           3 :         return OGRERR_FAILURE;
     724             :     }
     725             : 
     726          61 :     OGRFieldDefn *poFieldDefn = m_poFeatureDefn->GetFieldDefn(iField);
     727         122 :     auto oTemporaryUnsealer(poFieldDefn->GetTemporaryUnsealer());
     728             : 
     729         117 :     if ((nFlagsIn & ALTER_TYPE_FLAG) &&
     730          56 :         (poFieldDefn->GetType() != poNewFieldDefn->GetType() ||
     731           3 :          poFieldDefn->GetSubType() != poNewFieldDefn->GetSubType()))
     732             :     {
     733         106 :         if ((poNewFieldDefn->GetType() == OFTDate ||
     734         106 :              poNewFieldDefn->GetType() == OFTTime ||
     735         159 :              poNewFieldDefn->GetType() == OFTDateTime) &&
     736          12 :             (poFieldDefn->GetType() == OFTDate ||
     737           0 :              poFieldDefn->GetType() == OFTTime ||
     738           0 :              poFieldDefn->GetType() == OFTDateTime))
     739             :         {
     740             :             // Do nothing on features.
     741             :         }
     742          43 :         else if (poNewFieldDefn->GetType() == OFTInteger64 &&
     743           2 :                  poFieldDefn->GetType() == OFTInteger)
     744             :         {
     745             :             // Update all the internal features.  Hopefully there aren't any
     746             :             // external features referring to our OGRFeatureDefn!
     747           2 :             IOGRMemLayerFeatureIterator *poIter = GetIterator();
     748           2 :             OGRFeature *poFeature = nullptr;
     749           4 :             while ((poFeature = poIter->Next()) != nullptr)
     750             :             {
     751           2 :                 OGRField *poFieldRaw = poFeature->GetRawFieldRef(iField);
     752           4 :                 if (poFeature->IsFieldSetAndNotNull(iField) &&
     753           2 :                     !poFeature->IsFieldNull(iField))
     754             :                 {
     755           2 :                     const GIntBig nVal = poFieldRaw->Integer;
     756           2 :                     poFieldRaw->Integer64 = nVal;
     757             :                 }
     758             :             }
     759           2 :             delete poIter;
     760             :         }
     761          54 :         else if (poNewFieldDefn->GetType() == OFTReal &&
     762          15 :                  poFieldDefn->GetType() == OFTInteger)
     763             :         {
     764             :             // Update all the internal features.  Hopefully there aren't any
     765             :             // external features referring to our OGRFeatureDefn!
     766          15 :             IOGRMemLayerFeatureIterator *poIter = GetIterator();
     767          15 :             OGRFeature *poFeature = nullptr;
     768          30 :             while ((poFeature = poIter->Next()) != nullptr)
     769             :             {
     770          15 :                 OGRField *poFieldRaw = poFeature->GetRawFieldRef(iField);
     771          30 :                 if (poFeature->IsFieldSetAndNotNull(iField) &&
     772          15 :                     !poFeature->IsFieldNull(iField))
     773             :                 {
     774          15 :                     const double dfVal = poFieldRaw->Integer;
     775          15 :                     poFieldRaw->Real = dfVal;
     776             :                 }
     777             :             }
     778          15 :             delete poIter;
     779             :         }
     780          24 :         else if (poNewFieldDefn->GetType() == OFTReal &&
     781           0 :                  poFieldDefn->GetType() == OFTInteger64)
     782             :         {
     783             :             // Update all the internal features.  Hopefully there aren't any
     784             :             // external features referring to our OGRFeatureDefn!
     785           0 :             IOGRMemLayerFeatureIterator *poIter = GetIterator();
     786           0 :             OGRFeature *poFeature = nullptr;
     787           0 :             while ((poFeature = poIter->Next()) != nullptr)
     788             :             {
     789           0 :                 OGRField *poFieldRaw = poFeature->GetRawFieldRef(iField);
     790           0 :                 if (poFeature->IsFieldSetAndNotNull(iField) &&
     791           0 :                     !poFeature->IsFieldNull(iField))
     792             :                 {
     793           0 :                     const double dfVal =
     794           0 :                         static_cast<double>(poFieldRaw->Integer64);
     795           0 :                     poFieldRaw->Real = dfVal;
     796             :                 }
     797             :             }
     798           0 :             delete poIter;
     799             :         }
     800             :         else
     801             :         {
     802          24 :             if (poFieldDefn->GetType() != OGRUnknownType)
     803             :             {
     804          24 :                 if (poNewFieldDefn->GetType() != OFTString)
     805             :                 {
     806           0 :                     CPLError(CE_Failure, CPLE_NotSupported,
     807             :                              "Can only convert from OFTInteger to OFTReal, "
     808             :                              "or from anything to OFTString");
     809           0 :                     return OGRERR_FAILURE;
     810             :                 }
     811             :             }
     812             : 
     813             :             // Update all the internal features.  Hopefully there aren't any
     814             :             // external features referring to our OGRFeatureDefn!
     815          24 :             IOGRMemLayerFeatureIterator *poIter = GetIterator();
     816          24 :             OGRFeature *poFeature = nullptr;
     817         251 :             while ((poFeature = poIter->Next()) != nullptr)
     818             :             {
     819         227 :                 OGRField *poFieldRaw = poFeature->GetRawFieldRef(iField);
     820         249 :                 if (poFeature->IsFieldSetAndNotNull(iField) &&
     821          22 :                     !poFeature->IsFieldNull(iField))
     822             :                 {
     823             :                     char *pszVal =
     824          22 :                         CPLStrdup(poFeature->GetFieldAsString(iField));
     825             : 
     826             :                     // Little trick to unallocate the field.
     827             :                     OGRField sField;
     828          22 :                     OGR_RawField_SetUnset(&sField);
     829          22 :                     poFeature->SetField(iField, &sField);
     830             : 
     831          22 :                     poFieldRaw->String = pszVal;
     832             :                 }
     833             :             }
     834          24 :             delete poIter;
     835             :         }
     836             : 
     837          53 :         poFieldDefn->SetSubType(OFSTNone);
     838          53 :         poFieldDefn->SetType(poNewFieldDefn->GetType());
     839          53 :         poFieldDefn->SetSubType(poNewFieldDefn->GetSubType());
     840             :     }
     841             : 
     842          61 :     if (nFlagsIn & ALTER_NAME_FLAG)
     843           7 :         poFieldDefn->SetName(poNewFieldDefn->GetNameRef());
     844          61 :     if (nFlagsIn & ALTER_WIDTH_PRECISION_FLAG)
     845             :     {
     846           9 :         poFieldDefn->SetWidth(poNewFieldDefn->GetWidth());
     847           9 :         poFieldDefn->SetPrecision(poNewFieldDefn->GetPrecision());
     848             :     }
     849             : 
     850          61 :     m_bUpdated = true;
     851             : 
     852          61 :     return OGRERR_NONE;
     853             : }
     854             : 
     855             : /************************************************************************/
     856             : /*                         AlterGeomFieldDefn()                         */
     857             : /************************************************************************/
     858             : 
     859           7 : OGRErr OGRMemLayer::AlterGeomFieldDefn(
     860             :     int iGeomField, const OGRGeomFieldDefn *poNewGeomFieldDefn, int nFlagsIn)
     861             : {
     862           7 :     if (!m_bUpdatable)
     863           0 :         return OGRERR_FAILURE;
     864             : 
     865           7 :     if (iGeomField < 0 || iGeomField >= m_poFeatureDefn->GetGeomFieldCount())
     866             :     {
     867           0 :         CPLError(CE_Failure, CPLE_NotSupported, "Invalid field index");
     868           0 :         return OGRERR_FAILURE;
     869             :     }
     870             : 
     871           7 :     auto poFieldDefn = m_poFeatureDefn->GetGeomFieldDefn(iGeomField);
     872          14 :     auto oTemporaryUnsealer(poFieldDefn->GetTemporaryUnsealer());
     873             : 
     874           7 :     if (nFlagsIn & ALTER_GEOM_FIELD_DEFN_NAME_FLAG)
     875           5 :         poFieldDefn->SetName(poNewGeomFieldDefn->GetNameRef());
     876           7 :     if (nFlagsIn & ALTER_GEOM_FIELD_DEFN_TYPE_FLAG)
     877             :     {
     878           4 :         if (poNewGeomFieldDefn->GetType() == wkbNone)
     879           0 :             return OGRERR_FAILURE;
     880           4 :         poFieldDefn->SetType(poNewGeomFieldDefn->GetType());
     881             :     }
     882           7 :     if (nFlagsIn & ALTER_GEOM_FIELD_DEFN_NULLABLE_FLAG)
     883           4 :         poFieldDefn->SetNullable(poNewGeomFieldDefn->IsNullable());
     884             : 
     885           7 :     if (nFlagsIn & ALTER_GEOM_FIELD_DEFN_SRS_FLAG)
     886             :     {
     887           4 :         OGRSpatialReference *poSRSNew = nullptr;
     888           4 :         const auto poSRSNewRef = poNewGeomFieldDefn->GetSpatialRef();
     889           4 :         if (poSRSNewRef)
     890             :         {
     891           3 :             poSRSNew = poSRSNewRef->Clone();
     892           3 :             if ((nFlagsIn & ALTER_GEOM_FIELD_DEFN_SRS_COORD_EPOCH_FLAG) == 0)
     893             :             {
     894           0 :                 const auto poSRSOld = poFieldDefn->GetSpatialRef();
     895           0 :                 if (poSRSOld)
     896           0 :                     poSRSNew->SetCoordinateEpoch(
     897             :                         poSRSOld->GetCoordinateEpoch());
     898             :                 else
     899           0 :                     poSRSNew->SetCoordinateEpoch(0);
     900             :             }
     901             :         }
     902           4 :         poFieldDefn->SetSpatialRef(poSRSNew);
     903           4 :         if (poSRSNew)
     904           3 :             poSRSNew->Release();
     905             :     }
     906           3 :     else if (nFlagsIn & ALTER_GEOM_FIELD_DEFN_SRS_COORD_EPOCH_FLAG)
     907             :     {
     908           2 :         const auto poSRSOld = poFieldDefn->GetSpatialRef();
     909           2 :         const auto poSRSNewRef = poNewGeomFieldDefn->GetSpatialRef();
     910           2 :         if (poSRSOld && poSRSNewRef)
     911             :         {
     912           1 :             auto poSRSNew = poSRSOld->Clone();
     913           1 :             poSRSNew->SetCoordinateEpoch(poSRSNewRef->GetCoordinateEpoch());
     914           1 :             poFieldDefn->SetSpatialRef(poSRSNew);
     915           1 :             poSRSNew->Release();
     916             :         }
     917             :     }
     918             : 
     919           7 :     m_bUpdated = true;
     920             : 
     921           7 :     return OGRERR_NONE;
     922             : }
     923             : 
     924             : /************************************************************************/
     925             : /*                          CreateGeomField()                           */
     926             : /************************************************************************/
     927             : 
     928         352 : OGRErr OGRMemLayer::CreateGeomField(const OGRGeomFieldDefn *poGeomField,
     929             :                                     int /* bApproxOK */)
     930             : {
     931         352 :     if (!m_bUpdatable)
     932           0 :         return OGRERR_FAILURE;
     933             : 
     934             :     // Simple case, no features exist yet.
     935         352 :     if (m_nFeatureCount == 0)
     936             :     {
     937         349 :         whileUnsealing(m_poFeatureDefn)->AddGeomFieldDefn(poGeomField);
     938         349 :         return OGRERR_NONE;
     939             :     }
     940             : 
     941             :     // Add field definition and setup remap definition.
     942           3 :     whileUnsealing(m_poFeatureDefn)->AddGeomFieldDefn(poGeomField);
     943             : 
     944           3 :     const int nGeomFieldCount = m_poFeatureDefn->GetGeomFieldCount();
     945           6 :     std::vector<int> anRemap(nGeomFieldCount);
     946           9 :     for (int i = 0; i < nGeomFieldCount; ++i)
     947             :     {
     948           6 :         if (i < nGeomFieldCount - 1)
     949           3 :             anRemap[i] = i;
     950             :         else
     951           3 :             anRemap[i] = -1;
     952             :     }
     953             : 
     954             :     // Remap all the internal features.  Hopefully there aren't any
     955             :     // external features referring to our OGRFeatureDefn!
     956           3 :     auto poIter = std::unique_ptr<IOGRMemLayerFeatureIterator>(GetIterator());
     957           6 :     while (OGRFeature *poFeature = poIter->Next())
     958             :     {
     959           3 :         poFeature->RemapGeomFields(nullptr, anRemap.data());
     960           3 :     }
     961             : 
     962           3 :     m_bUpdated = true;
     963             : 
     964           3 :     return OGRERR_NONE;
     965             : }
     966             : 
     967             : /************************************************************************/
     968             : /*                        OGRMemLayerIteratorArray                      */
     969             : /************************************************************************/
     970             : 
     971             : class OGRMemLayerIteratorArray final : public IOGRMemLayerFeatureIterator
     972             : {
     973             :     GIntBig m_iCurIdx = 0;
     974             :     const GIntBig m_nMaxFeatureCount;
     975             :     OGRFeature **const m_papoFeatures;
     976             : 
     977             :   public:
     978         427 :     OGRMemLayerIteratorArray(GIntBig nMaxFeatureCount,
     979             :                              OGRFeature **papoFeatures)
     980         427 :         : m_nMaxFeatureCount(nMaxFeatureCount), m_papoFeatures(papoFeatures)
     981             :     {
     982         427 :     }
     983             : 
     984        4871 :     virtual OGRFeature *Next() override
     985             :     {
     986        4871 :         while (m_iCurIdx < m_nMaxFeatureCount)
     987             :         {
     988        4444 :             OGRFeature *poFeature = m_papoFeatures[m_iCurIdx];
     989        4444 :             ++m_iCurIdx;
     990        4444 :             if (poFeature != nullptr)
     991         878 :                 return poFeature;
     992             :         }
     993         427 :         return nullptr;
     994             :     }
     995             : };
     996             : 
     997             : /************************************************************************/
     998             : /*                         OGRMemLayerIteratorMap                       */
     999             : /************************************************************************/
    1000             : 
    1001             : class OGRMemLayerIteratorMap final : public IOGRMemLayerFeatureIterator
    1002             : {
    1003             :     typedef std::map<GIntBig, std::unique_ptr<OGRFeature>> FeatureMap;
    1004             :     typedef FeatureMap::iterator FeatureIterator;
    1005             : 
    1006             :     const FeatureMap &m_oMapFeatures;
    1007             :     FeatureIterator m_oIter;
    1008             : 
    1009             :   public:
    1010           1 :     explicit OGRMemLayerIteratorMap(FeatureMap &oMapFeatures)
    1011           1 :         : m_oMapFeatures(oMapFeatures), m_oIter(oMapFeatures.begin())
    1012             :     {
    1013           1 :     }
    1014             : 
    1015           2 :     virtual OGRFeature *Next() override
    1016             :     {
    1017           2 :         if (m_oIter != m_oMapFeatures.end())
    1018             :         {
    1019           1 :             OGRFeature *poFeature = m_oIter->second.get();
    1020           1 :             ++m_oIter;
    1021           1 :             return poFeature;
    1022             :         }
    1023           1 :         return nullptr;
    1024             :     }
    1025             : 
    1026             :   private:
    1027             :     CPL_DISALLOW_COPY_ASSIGN(OGRMemLayerIteratorMap)
    1028             : };
    1029             : 
    1030             : /************************************************************************/
    1031             : /*                            GetIterator()                             */
    1032             : /************************************************************************/
    1033             : 
    1034         428 : IOGRMemLayerFeatureIterator *OGRMemLayer::GetIterator()
    1035             : {
    1036         428 :     if (m_oMapFeatures.empty())
    1037         427 :         return new OGRMemLayerIteratorArray(m_nMaxFeatureCount, m_papoFeatures);
    1038             : 
    1039           1 :     return new OGRMemLayerIteratorMap(m_oMapFeatures);
    1040             : }

Generated by: LCOV version 1.14