Coverage Report

Created: 2025-12-31 06:48

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