Coverage Report

Created: 2025-06-13 06:29

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