LCOV - code coverage report
Current view: top level - frmts/mem - ogrmemlayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 411 461 89.2 %
Date: 2025-09-10 17:48:50 Functions: 28 29 96.6 %

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

Generated by: LCOV version 1.14