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

Generated by: LCOV version 1.14