Coverage Report

Created: 2026-07-14 06:21

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