Coverage Report

Created: 2025-08-28 06:57

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