Coverage Report

Created: 2026-02-14 09:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/ogr/ogr_feature.h
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  OpenGIS Simple Features Reference Implementation
4
 * Purpose:  Class for representing a whole feature, and layer schemas.
5
 * Author:   Frank Warmerdam, warmerdam@pobox.com
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 1999,  Les Technologies SoftMap Inc.
9
 * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
10
 *
11
 * SPDX-License-Identifier: MIT
12
 ****************************************************************************/
13
14
#ifndef OGR_FEATURE_H_INCLUDED
15
#define OGR_FEATURE_H_INCLUDED
16
17
#include "cpl_atomic_ops.h"
18
#include "gdal_fwd.h"
19
#include "ogr_featurestyle.h"
20
#include "ogr_geometry.h"
21
#include "ogr_geomcoordinateprecision.h"
22
23
#include <cstddef>
24
25
#include <exception>
26
#include <memory>
27
#include <string>
28
#include <vector>
29
30
/**
31
 * \file ogr_feature.h
32
 *
33
 * Simple feature classes.
34
 */
35
36
class OGRStyleTable;
37
38
/************************************************************************/
39
/*                             OGRFieldDefn                             */
40
/************************************************************************/
41
42
/**
43
 * Definition of an attribute of an OGRFeatureDefn. A field is described by :
44
 * <ul>
45
 * <li>a name. See SetName() / GetNameRef()</li>
46
 * <li>an alternative name (optional): alternative descriptive name for the
47
 * field (sometimes referred to as an "alias"). See SetAlternativeName() /
48
 * GetAlternativeNameRef()</li> <li>a type: OFTString, OFTInteger, OFTReal, ...
49
 * See SetType() / GetType()</li> <li>a subtype (optional): OFSTBoolean, ... See
50
 * SetSubType() / GetSubType()</li> <li>a width (optional): maximal number of
51
 * characters. See SetWidth() / GetWidth()</li> <li>a precision (optional):
52
 * number of digits after decimal point. See SetPrecision() /
53
 * GetPrecision()</li> <li>a NOT NULL constraint (optional). See SetNullable() /
54
 * IsNullable()</li> <li>a UNIQUE constraint (optional). See SetUnique() /
55
 * IsUnique()</li> <li>a default value (optional).  See SetDefault() /
56
 * GetDefault()</li> <li>a boolean to indicate whether it should be ignored when
57
 * retrieving features.  See SetIgnored() / IsIgnored()</li> <li>a field domain
58
 * name (optional). See SetDomainName() / Get DomainName()</li>
59
 * </ul>
60
 *
61
 * Note that once a OGRFieldDefn has been added to a layer definition with
62
 * OGRLayer::AddFieldDefn(), its setter methods should not be called on the
63
 * object returned with OGRLayer::GetLayerDefn()->GetFieldDefn(). Instead,
64
 * OGRLayer::AlterFieldDefn() should be called on a new instance of
65
 * OGRFieldDefn, for drivers that support AlterFieldDefn().
66
 */
67
68
class CPL_DLL OGRFieldDefn
69
{
70
  private:
71
    char *pszName;
72
    char *pszAlternativeName;
73
    OGRFieldType eType;
74
    OGRJustification eJustify;
75
    int nWidth;  // Zero is variable.
76
    int nPrecision;
77
    char *pszDefault;
78
79
    int bIgnore;
80
    OGRFieldSubType eSubType;
81
82
    int bNullable;
83
    int bUnique;
84
85
    // Used by drivers (GPKG) to track generated fields
86
    bool m_bGenerated = false;
87
88
    std::string m_osDomainName{};  // field domain name. Might be empty
89
90
    std::string m_osComment{};  // field comment. Might be empty
91
92
    int m_nTZFlag = OGR_TZFLAG_UNKNOWN;
93
    bool m_bSealed = false;
94
95
  public:
96
    OGRFieldDefn(const char *, OGRFieldType);
97
    explicit OGRFieldDefn(const OGRFieldDefn *);
98
    ~OGRFieldDefn();
99
100
    // Copy constructor
101
    OGRFieldDefn(const OGRFieldDefn &oOther);
102
103
    // Copy assignment operator
104
    OGRFieldDefn &operator=(const OGRFieldDefn &oOther);
105
106
    void SetName(const char *);
107
108
    const char *GetNameRef() const
109
423M
    {
110
423M
        return pszName;
111
423M
    }
112
113
    void SetAlternativeName(const char *);
114
115
    const char *GetAlternativeNameRef() const
116
6.04M
    {
117
6.04M
        return pszAlternativeName;
118
6.04M
    }
119
120
    OGRFieldType GetType() const
121
1.75G
    {
122
1.75G
        return eType;
123
1.75G
    }
124
125
    void SetType(OGRFieldType eTypeIn);
126
    static const char *GetFieldTypeName(OGRFieldType);
127
    static OGRFieldType GetFieldTypeByName(const char *);
128
129
    OGRFieldSubType GetSubType() const
130
71.4M
    {
131
71.4M
        return eSubType;
132
71.4M
    }
133
134
    void SetSubType(OGRFieldSubType eSubTypeIn);
135
    static const char *GetFieldSubTypeName(OGRFieldSubType);
136
    static OGRFieldSubType GetFieldSubTypeByName(const char *);
137
138
    OGRJustification GetJustify() const
139
5.89M
    {
140
5.89M
        return eJustify;
141
5.89M
    }
142
143
    void SetJustify(OGRJustification eJustifyIn)
144
9.21k
    {
145
9.21k
        eJustify = eJustifyIn;
146
9.21k
    }
147
148
    int GetWidth() const
149
31.2M
    {
150
31.2M
        return nWidth;
151
31.2M
    }
152
153
    void SetWidth(int nWidthIn);
154
155
    int GetPrecision() const
156
5.94M
    {
157
5.94M
        return nPrecision;
158
5.94M
    }
159
160
    void SetPrecision(int nPrecisionIn);
161
162
    int GetTZFlag() const
163
5.89M
    {
164
5.89M
        return m_nTZFlag;
165
5.89M
    }
166
167
    void SetTZFlag(int nTZFlag);
168
169
    void Set(const char *, OGRFieldType, int = 0, int = 0,
170
             OGRJustification = OJUndefined);
171
172
    void SetDefault(const char *);
173
    const char *GetDefault() const;
174
    int IsDefaultDriverSpecific() const;
175
176
    int IsIgnored() const
177
23.5M
    {
178
23.5M
        return bIgnore;
179
23.5M
    }
180
181
    void SetIgnored(int bIgnoreIn)
182
113k
    {
183
113k
        bIgnore = bIgnoreIn;
184
113k
    }
185
186
    int IsNullable() const
187
14.2M
    {
188
14.2M
        return bNullable;
189
14.2M
    }
190
191
    void SetNullable(int bNullableIn);
192
193
    int IsUnique() const
194
6.02M
    {
195
6.02M
        return bUnique;
196
6.02M
    }
197
198
    /**
199
     * @brief Return whether the field is a generated field.
200
     *
201
     * At time of writing, only the GeoPackage and PG drivers fill that information. Consequently,
202
     * only a returned value equal to TRUE can be fully trusted.
203
     * @return TRUE if the field is a generated field, FALSE otherwise.
204
     * @since GDAL 3.11
205
     */
206
    bool IsGenerated() const
207
6.94M
    {
208
6.94M
        return m_bGenerated;
209
6.94M
    }
210
211
    /**
212
     * @brief SetGenerated set the field generated status.
213
     * @param bGeneratedIn TRUE if the field is a generated field, FALSE otherwise.
214
     * @since GDAL 3.11
215
     */
216
    void SetGenerated(bool bGeneratedIn)
217
3.19k
    {
218
3.19k
        m_bGenerated = bGeneratedIn;
219
3.19k
    }
220
221
    void SetUnique(int bUniqueIn);
222
223
    const std::string &GetDomainName() const
224
2.18M
    {
225
2.18M
        return m_osDomainName;
226
2.18M
    }
227
228
    void SetDomainName(const std::string &osDomainName);
229
230
    const std::string &GetComment() const
231
5.98M
    {
232
5.98M
        return m_osComment;
233
5.98M
    }
234
235
    void SetComment(const std::string &osComment);
236
237
    int IsSame(const OGRFieldDefn *) const;
238
239
    /** Convert a OGRFieldDefn* to a OGRFieldDefnH.
240
     */
241
    static inline OGRFieldDefnH ToHandle(OGRFieldDefn *poFieldDefn)
242
48.7k
    {
243
48.7k
        return reinterpret_cast<OGRFieldDefnH>(poFieldDefn);
244
48.7k
    }
245
246
    /** Convert a OGRFieldDefnH to a OGRFieldDefn*.
247
     */
248
    static inline OGRFieldDefn *FromHandle(OGRFieldDefnH hFieldDefn)
249
146k
    {
250
146k
        return reinterpret_cast<OGRFieldDefn *>(hFieldDefn);
251
146k
    }
252
253
    void Seal();
254
255
    void Unseal();
256
257
    /*! @cond Doxygen_Suppress */
258
    struct CPL_DLL TemporaryUnsealer
259
    {
260
      private:
261
        OGRFieldDefn *m_poFieldDefn = nullptr;
262
        CPL_DISALLOW_COPY_ASSIGN(TemporaryUnsealer)
263
      public:
264
        explicit TemporaryUnsealer(OGRFieldDefn *poFieldDefn)
265
64.8k
            : m_poFieldDefn(poFieldDefn)
266
64.8k
        {
267
64.8k
            m_poFieldDefn->Unseal();
268
64.8k
        }
269
270
        TemporaryUnsealer(TemporaryUnsealer &&) = default;
271
        TemporaryUnsealer &operator=(TemporaryUnsealer &&) = default;
272
273
        ~TemporaryUnsealer()
274
64.8k
        {
275
64.8k
            m_poFieldDefn->Seal();
276
64.8k
        }
277
278
        OGRFieldDefn *operator->()
279
273
        {
280
273
            return m_poFieldDefn;
281
273
        }
282
    };
283
284
    /*! @endcond */
285
286
    TemporaryUnsealer GetTemporaryUnsealer();
287
};
288
289
#ifdef GDAL_COMPILATION
290
/** Return an object that temporary unseals the OGRFieldDefn.
291
 *
292
 * The returned object calls Unseal() initially, and when it is destroyed
293
 * it calls Seal().
294
 *
295
 * This method should only be called by driver implementations.
296
 *
297
 * Usage: whileUnsealing(poFieldDefn)->some_method();
298
 *
299
 * @since GDAL 3.9
300
 */
301
inline OGRFieldDefn::TemporaryUnsealer whileUnsealing(OGRFieldDefn *object)
302
273
{
303
273
    return object->GetTemporaryUnsealer();
304
273
}
305
#endif
306
307
/************************************************************************/
308
/*                           OGRGeomFieldDefn                           */
309
/************************************************************************/
310
311
/**
312
 * Definition of a geometry field of an OGRFeatureDefn. A geometry field is
313
 * described by :
314
 * <ul>
315
 * <li>a name. See SetName() / GetNameRef()</li>
316
 * <li>a type: wkbPoint, wkbLineString, ... See SetType() / GetType()</li>
317
 * <li>a spatial reference system (optional). See SetSpatialRef() /
318
 * GetSpatialRef()</li> <li>a NOT NULL constraint (optional). See SetNullable()
319
 * / IsNullable()</li> <li>a boolean to indicate whether it should be ignored
320
 * when retrieving features.  See SetIgnored() / IsIgnored()</li>
321
 * </ul>
322
 *
323
 * Note that once a OGRGeomFieldDefn has been added to a layer definition with
324
 * OGRLayer::AddGeomFieldDefn(), its setter methods should not be called on the
325
 * object returned with OGRLayer::GetLayerDefn()->GetGeomFieldDefn(). Instead,
326
 * OGRLayer::AlterGeomFieldDefn() should be called on a new instance of
327
 * OGRFieldDefn, for drivers that support AlterFieldDefn().
328
 *
329
 */
330
331
class CPL_DLL OGRGeomFieldDefn
332
{
333
  protected:
334
    //! @cond Doxygen_Suppress
335
    char *pszName = nullptr;
336
    OGRwkbGeometryType eGeomType =
337
        wkbUnknown; /* all values possible except wkbNone */
338
    mutable const OGRSpatialReference *poSRS = nullptr;
339
340
    int bIgnore = false;
341
    mutable int bNullable = true;
342
    bool m_bSealed = false;
343
    OGRGeomCoordinatePrecision m_oCoordPrecision{};
344
345
    void Initialize(const char *, OGRwkbGeometryType);
346
    //! @endcond
347
348
  public:
349
    OGRGeomFieldDefn(const char *pszNameIn, OGRwkbGeometryType eGeomTypeIn);
350
    explicit OGRGeomFieldDefn(const OGRGeomFieldDefn *);
351
    virtual ~OGRGeomFieldDefn();
352
353
    // Copy constructor
354
    OGRGeomFieldDefn(const OGRGeomFieldDefn &oOther);
355
356
    // Move constructor
357
    OGRGeomFieldDefn(OGRGeomFieldDefn &&oOther);
358
359
    // Copy assignment operator
360
    OGRGeomFieldDefn &operator=(const OGRGeomFieldDefn &oOther);
361
362
    // Move assignment operator
363
    OGRGeomFieldDefn &operator=(OGRGeomFieldDefn &&oOther);
364
365
    void SetName(const char *);
366
367
    const char *GetNameRef() const
368
12.3M
    {
369
12.3M
        return pszName;
370
12.3M
    }
371
372
    OGRwkbGeometryType GetType() const
373
1.35M
    {
374
1.35M
        return eGeomType;
375
1.35M
    }
376
377
    void SetType(OGRwkbGeometryType eTypeIn);
378
379
    virtual const OGRSpatialReference *GetSpatialRef() const;
380
    void SetSpatialRef(const OGRSpatialReference *poSRSIn);
381
382
    int IsIgnored() const
383
5.87M
    {
384
5.87M
        return bIgnore;
385
5.87M
    }
386
387
    void SetIgnored(int bIgnoreIn)
388
17.7k
    {
389
17.7k
        bIgnore = bIgnoreIn;
390
17.7k
    }
391
392
    int IsNullable() const
393
690k
    {
394
690k
        return bNullable;
395
690k
    }
396
397
    void SetNullable(int bNullableIn);
398
399
    const OGRGeomCoordinatePrecision &GetCoordinatePrecision() const
400
25.8k
    {
401
25.8k
        return m_oCoordPrecision;
402
25.8k
    }
403
404
    void SetCoordinatePrecision(const OGRGeomCoordinatePrecision &prec);
405
406
    int IsSame(const OGRGeomFieldDefn *) const;
407
408
    /** Convert a OGRGeomFieldDefn* to a OGRGeomFieldDefnH.
409
     */
410
    static inline OGRGeomFieldDefnH ToHandle(OGRGeomFieldDefn *poGeomFieldDefn)
411
0
    {
412
0
        return reinterpret_cast<OGRGeomFieldDefnH>(poGeomFieldDefn);
413
0
    }
414
415
    /** Convert a OGRGeomFieldDefnH to a OGRGeomFieldDefn*.
416
     */
417
    static inline OGRGeomFieldDefn *FromHandle(OGRGeomFieldDefnH hGeomFieldDefn)
418
0
    {
419
0
        return reinterpret_cast<OGRGeomFieldDefn *>(hGeomFieldDefn);
420
0
    }
421
422
    void Seal();
423
424
    void Unseal();
425
426
    /*! @cond Doxygen_Suppress */
427
    struct CPL_DLL TemporaryUnsealer
428
    {
429
      private:
430
        OGRGeomFieldDefn *m_poFieldDefn = nullptr;
431
        CPL_DISALLOW_COPY_ASSIGN(TemporaryUnsealer)
432
      public:
433
        explicit TemporaryUnsealer(OGRGeomFieldDefn *poFieldDefn)
434
870
            : m_poFieldDefn(poFieldDefn)
435
870
        {
436
870
            m_poFieldDefn->Unseal();
437
870
        }
438
439
        TemporaryUnsealer(TemporaryUnsealer &&) = default;
440
        TemporaryUnsealer &operator=(TemporaryUnsealer &&) = default;
441
442
        ~TemporaryUnsealer()
443
870
        {
444
870
            m_poFieldDefn->Seal();
445
870
        }
446
447
        OGRGeomFieldDefn *operator->()
448
870
        {
449
870
            return m_poFieldDefn;
450
870
        }
451
    };
452
453
    /*! @endcond */
454
455
    TemporaryUnsealer GetTemporaryUnsealer();
456
};
457
458
#ifdef GDAL_COMPILATION
459
/** Return an object that temporary unseals the OGRGeomFieldDefn.
460
 *
461
 * The returned object calls Unseal() initially, and when it is destroyed
462
 * it calls Seal().
463
 *
464
 * This method should only be called by driver implementations.
465
 *
466
 * Usage: whileUnsealing(poGeomFieldDefn)->some_method();
467
 *
468
 * @since GDAL 3.9
469
 */
470
inline OGRGeomFieldDefn::TemporaryUnsealer
471
whileUnsealing(OGRGeomFieldDefn *object)
472
870
{
473
870
    return object->GetTemporaryUnsealer();
474
870
}
475
#endif
476
477
/************************************************************************/
478
/*                            OGRFeatureDefn                            */
479
/************************************************************************/
480
481
/**
482
 * Definition of a feature class or feature layer.
483
 *
484
 * This object contains schema information for a set of OGRFeatures.  In
485
 * table based systems, an OGRFeatureDefn is essentially a layer.  In more
486
 * object oriented approaches (such as SF CORBA) this can represent a class
487
 * of features but doesn't necessarily relate to all of a layer, or just one
488
 * layer.
489
 *
490
 * This object also can contain some other information such as a name and
491
 * potentially other metadata.
492
 *
493
 * It is essentially a collection of field descriptions (OGRFieldDefn class).
494
 * In addition to attribute fields, it can also
495
 * contain multiple geometry fields (OGRGeomFieldDefn class).
496
 *
497
 * It is reasonable for different translators to derive classes from
498
 * OGRFeatureDefn with additional translator specific information.
499
 *
500
 * Note that adding, modifying, removing, reordering a OGRFieldDefn (or a
501
 * OGRGeomFieldDefn) from/to a OGRFeatureDefn that belongs to a OGRLayer should
502
 * not be done through the OGRFeatureDefn::AddFieldDefn(),
503
 * OGRFeatureDefn::DeleteFieldDefn() or OGRFeatureDefn::ReorderFieldDefns()
504
 * methods, but rather through OGRLayer::CreateField(),
505
 * OGRLayer::AlterFieldDefn() or OGRLayer::ReorderFields(), for drivers that
506
 * support those operations.
507
 */
508
509
class CPL_DLL OGRFeatureDefn
510
{
511
  protected:
512
    //! @cond Doxygen_Suppress
513
    volatile int nRefCount = 0;
514
515
    mutable std::vector<std::unique_ptr<OGRFieldDefn>> apoFieldDefn{};
516
    mutable std::vector<std::unique_ptr<OGRGeomFieldDefn>> apoGeomFieldDefn{};
517
518
    char *pszFeatureClassName = nullptr;
519
520
    bool bIgnoreStyle = false;
521
522
    friend class TemporaryUnsealer;
523
    bool m_bSealed = false;
524
    int m_nTemporaryUnsealCount = 0;
525
    //! @endcond
526
527
  public:
528
    explicit OGRFeatureDefn(const char *pszName = nullptr);
529
    virtual ~OGRFeatureDefn();
530
531
    void SetName(const char *pszName);
532
    virtual const char *GetName() const;
533
534
    virtual int GetFieldCount() const;
535
    virtual OGRFieldDefn *GetFieldDefn(int i);
536
    virtual const OGRFieldDefn *GetFieldDefn(int i) const;
537
    virtual int GetFieldIndex(const char *) const;
538
    int GetFieldIndexCaseSensitive(const char *) const;
539
540
    //! @cond Doxygen_Suppress
541
    /** Helper class to iterate over non-geometry fields.
542
     *
543
     * Note: fields should not be added or removed while iterating over them.
544
     */
545
    template <class OwnerT, class ChildT> struct CPL_DLL Fields
546
    {
547
      private:
548
        OwnerT m_poFDefn;
549
550
      public:
551
0
        inline explicit Fields(OwnerT poFDefn) : m_poFDefn(poFDefn)
552
0
        {
553
0
        }
Unexecuted instantiation: OGRFeatureDefn::Fields<OGRFeatureDefn*, OGRFieldDefn*>::Fields(OGRFeatureDefn*)
Unexecuted instantiation: OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*>::Fields(OGRFeatureDefn const*)
554
555
        struct CPL_DLL Iterator
556
        {
557
          private:
558
            OwnerT m_poFDefn;
559
            int m_nIdx;
560
561
          public:
562
            inline Iterator(OwnerT poFDefn, int nIdx)
563
0
                : m_poFDefn(poFDefn), m_nIdx(nIdx)
564
0
            {
565
0
            }
Unexecuted instantiation: OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*>::Iterator::Iterator(OGRFeatureDefn const*, int)
Unexecuted instantiation: OGRFeatureDefn::Fields<OGRFeatureDefn*, OGRFieldDefn*>::Iterator::Iterator(OGRFeatureDefn*, int)
566
567
            inline ChildT operator*() const
568
0
            {
569
0
                return m_poFDefn->GetFieldDefn(m_nIdx);
570
0
            }
Unexecuted instantiation: OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*>::Iterator::operator*() const
Unexecuted instantiation: OGRFeatureDefn::Fields<OGRFeatureDefn*, OGRFieldDefn*>::Iterator::operator*() const
571
572
            inline Iterator &operator++()
573
0
            {
574
0
                m_nIdx++;
575
0
                return *this;
576
0
            }
Unexecuted instantiation: OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*>::Iterator::operator++()
Unexecuted instantiation: OGRFeatureDefn::Fields<OGRFeatureDefn*, OGRFieldDefn*>::Iterator::operator++()
577
578
            inline bool operator!=(const Iterator &it) const
579
0
            {
580
0
                return m_nIdx != it.m_nIdx;
581
0
            }
Unexecuted instantiation: OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*>::Iterator::operator!=(OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*>::Iterator const&) const
Unexecuted instantiation: OGRFeatureDefn::Fields<OGRFeatureDefn*, OGRFieldDefn*>::Iterator::operator!=(OGRFeatureDefn::Fields<OGRFeatureDefn*, OGRFieldDefn*>::Iterator const&) const
582
        };
583
584
        inline Iterator begin()
585
0
        {
586
0
            return Iterator(m_poFDefn, 0);
587
0
        }
Unexecuted instantiation: OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*>::begin()
Unexecuted instantiation: OGRFeatureDefn::Fields<OGRFeatureDefn*, OGRFieldDefn*>::begin()
588
589
        inline Iterator end()
590
0
        {
591
0
            return Iterator(m_poFDefn, m_poFDefn->GetFieldCount());
592
0
        }
Unexecuted instantiation: OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*>::end()
Unexecuted instantiation: OGRFeatureDefn::Fields<OGRFeatureDefn*, OGRFieldDefn*>::end()
593
594
        inline size_t size() const
595
        {
596
            return static_cast<std::size_t>(m_poFDefn->GetFieldCount());
597
        }
598
599
        inline ChildT operator[](size_t i)
600
        {
601
            return m_poFDefn->GetFieldDefn(static_cast<int>(i));
602
        }
603
    };
604
605
    //! @endcond
606
607
    /** Return type of GetFields() */
608
    using NonConstFields = Fields<OGRFeatureDefn *, OGRFieldDefn *>;
609
610
    /** Return an object that can be used to iterate over non-geometry fields.
611
        \verbatim
612
        for( const auto* poFieldDefn: poFeatureDefn->GetFields() )
613
        {
614
            // do something
615
        }
616
        \endverbatim
617
618
        @since GDAL 3.7
619
     */
620
    inline NonConstFields GetFields()
621
0
    {
622
0
        return NonConstFields(this);
623
0
    }
624
625
    /** Return type of GetFields() const */
626
    using ConstFields = Fields<const OGRFeatureDefn *, const OGRFieldDefn *>;
627
628
    /** Return an object that can be used to iterate over non-geometry fields.
629
        \verbatim
630
        for( const auto* poFieldDefn: poFeatureDefn->GetFields() )
631
        {
632
            // do something
633
        }
634
        \endverbatim
635
636
        @since GDAL 3.12
637
     */
638
    inline ConstFields GetFields() const
639
0
    {
640
0
        return ConstFields(this);
641
0
    }
642
643
    //! @cond Doxygen_Suppress
644
    // That method should only be called if there's a guarantee that
645
    // GetFieldCount() has been called before
646
    int GetFieldCountUnsafe() const
647
356M
    {
648
356M
        return static_cast<int>(apoFieldDefn.size());
649
356M
    }
650
651
    // Those methods don't check i is n range.
652
    OGRFieldDefn *GetFieldDefnUnsafe(int i)
653
1.37M
    {
654
1.37M
        if (apoFieldDefn.empty())
655
0
            GetFieldDefn(i);
656
1.37M
        return apoFieldDefn[static_cast<std::size_t>(i)].get();
657
1.37M
    }
658
659
    const OGRFieldDefn *GetFieldDefnUnsafe(int i) const
660
540M
    {
661
540M
        if (apoFieldDefn.empty())
662
0
            GetFieldDefn(i);
663
540M
        return apoFieldDefn[static_cast<std::size_t>(i)].get();
664
540M
    }
665
666
    //! @endcond
667
668
    virtual void AddFieldDefn(const OGRFieldDefn *);
669
    virtual OGRErr DeleteFieldDefn(int iField);
670
671
    /**
672
     * @brief StealFieldDefn takes ownership of the field definition at index detaching
673
     *        it from the feature definition.
674
     * This is an advanced method designed to be only used for driver implementations.
675
     * @param iField index of the field definition to detach.
676
     * @return a unique pointer to the detached field definition or nullptr if the index is out of range.
677
     * @since GDAL 3.11
678
     */
679
    virtual std::unique_ptr<OGRFieldDefn> StealFieldDefn(int iField);
680
681
    virtual void AddFieldDefn(std::unique_ptr<OGRFieldDefn> &&poFieldDefn);
682
683
    virtual OGRErr ReorderFieldDefns(const int *panMap);
684
685
    /**
686
     * @brief StealGeomFieldDefn takes ownership of the the geometry field definition at index
687
     *        detaching it from the feature definition.
688
     * This is an advanced method designed to be only used for driver implementations.
689
     * @param iField index of the geometry field definition to detach.
690
     * @return a unique pointer to the detached geometry field definition or nullptr if the index is out of range.
691
     * @since GDAL 3.11
692
     */
693
    virtual std::unique_ptr<OGRGeomFieldDefn> StealGeomFieldDefn(int iField);
694
695
    virtual int GetGeomFieldCount() const;
696
    virtual OGRGeomFieldDefn *GetGeomFieldDefn(int i);
697
    virtual const OGRGeomFieldDefn *GetGeomFieldDefn(int i) const;
698
    virtual int GetGeomFieldIndex(const char *) const;
699
700
    //! @cond Doxygen_Suppress
701
    /** Helper class to iterate over geometry fields.
702
     *
703
     * Note: fields should not be added or removed while iterating over them.
704
     */
705
    template <class OwnerT, class ChildT> struct CPL_DLL GeomFields
706
    {
707
      private:
708
        OwnerT m_poFDefn;
709
710
      public:
711
2.80M
        inline explicit GeomFields(OwnerT poFDefn) : m_poFDefn(poFDefn)
712
2.80M
        {
713
2.80M
        }
OGRFeatureDefn::GeomFields<OGRFeatureDefn const*, OGRGeomFieldDefn const*>::GeomFields(OGRFeatureDefn const*)
Line
Count
Source
711
2.80M
        inline explicit GeomFields(OwnerT poFDefn) : m_poFDefn(poFDefn)
712
2.80M
        {
713
2.80M
        }
Unexecuted instantiation: OGRFeatureDefn::GeomFields<OGRFeatureDefn*, OGRGeomFieldDefn*>::GeomFields(OGRFeatureDefn*)
714
715
        struct CPL_DLL Iterator
716
        {
717
          private:
718
            OwnerT m_poFDefn;
719
            int m_nIdx;
720
721
          public:
722
            inline Iterator(OwnerT poFDefn, int nIdx)
723
5.60M
                : m_poFDefn(poFDefn), m_nIdx(nIdx)
724
5.60M
            {
725
5.60M
            }
OGRFeatureDefn::GeomFields<OGRFeatureDefn const*, OGRGeomFieldDefn const*>::Iterator::Iterator(OGRFeatureDefn const*, int)
Line
Count
Source
723
5.60M
                : m_poFDefn(poFDefn), m_nIdx(nIdx)
724
5.60M
            {
725
5.60M
            }
Unexecuted instantiation: OGRFeatureDefn::GeomFields<OGRFeatureDefn*, OGRGeomFieldDefn*>::Iterator::Iterator(OGRFeatureDefn*, int)
726
727
            inline ChildT operator*() const
728
2.80M
            {
729
2.80M
                return m_poFDefn->GetGeomFieldDefn(m_nIdx);
730
2.80M
            }
OGRFeatureDefn::GeomFields<OGRFeatureDefn const*, OGRGeomFieldDefn const*>::Iterator::operator*() const
Line
Count
Source
728
2.80M
            {
729
2.80M
                return m_poFDefn->GetGeomFieldDefn(m_nIdx);
730
2.80M
            }
Unexecuted instantiation: OGRFeatureDefn::GeomFields<OGRFeatureDefn*, OGRGeomFieldDefn*>::Iterator::operator*() const
731
732
            inline Iterator &operator++()
733
2.80M
            {
734
2.80M
                m_nIdx++;
735
2.80M
                return *this;
736
2.80M
            }
OGRFeatureDefn::GeomFields<OGRFeatureDefn const*, OGRGeomFieldDefn const*>::Iterator::operator++()
Line
Count
Source
733
2.80M
            {
734
2.80M
                m_nIdx++;
735
2.80M
                return *this;
736
2.80M
            }
Unexecuted instantiation: OGRFeatureDefn::GeomFields<OGRFeatureDefn*, OGRGeomFieldDefn*>::Iterator::operator++()
737
738
            inline bool operator!=(const Iterator &it) const
739
5.60M
            {
740
5.60M
                return m_nIdx != it.m_nIdx;
741
5.60M
            }
OGRFeatureDefn::GeomFields<OGRFeatureDefn const*, OGRGeomFieldDefn const*>::Iterator::operator!=(OGRFeatureDefn::GeomFields<OGRFeatureDefn const*, OGRGeomFieldDefn const*>::Iterator const&) const
Line
Count
Source
739
5.60M
            {
740
5.60M
                return m_nIdx != it.m_nIdx;
741
5.60M
            }
Unexecuted instantiation: OGRFeatureDefn::GeomFields<OGRFeatureDefn*, OGRGeomFieldDefn*>::Iterator::operator!=(OGRFeatureDefn::GeomFields<OGRFeatureDefn*, OGRGeomFieldDefn*>::Iterator const&) const
742
        };
743
744
        inline Iterator begin()
745
2.80M
        {
746
2.80M
            return Iterator(m_poFDefn, 0);
747
2.80M
        }
OGRFeatureDefn::GeomFields<OGRFeatureDefn const*, OGRGeomFieldDefn const*>::begin()
Line
Count
Source
745
2.80M
        {
746
2.80M
            return Iterator(m_poFDefn, 0);
747
2.80M
        }
Unexecuted instantiation: OGRFeatureDefn::GeomFields<OGRFeatureDefn*, OGRGeomFieldDefn*>::begin()
748
749
        inline Iterator end()
750
2.80M
        {
751
2.80M
            return Iterator(m_poFDefn, m_poFDefn->GetGeomFieldCount());
752
2.80M
        }
OGRFeatureDefn::GeomFields<OGRFeatureDefn const*, OGRGeomFieldDefn const*>::end()
Line
Count
Source
750
2.80M
        {
751
2.80M
            return Iterator(m_poFDefn, m_poFDefn->GetGeomFieldCount());
752
2.80M
        }
Unexecuted instantiation: OGRFeatureDefn::GeomFields<OGRFeatureDefn*, OGRGeomFieldDefn*>::end()
753
754
        inline size_t size() const
755
        {
756
            return static_cast<std::size_t>(m_poFDefn->GetGeomFieldCount());
757
        }
758
759
        inline ChildT operator[](size_t i) const
760
        {
761
            return m_poFDefn->GetGeomFieldDefn(static_cast<int>(i));
762
        }
763
    };
764
765
    //! @endcond
766
767
    /** Return type of GetGeomFields() */
768
    using NonConstGeomFields = GeomFields<OGRFeatureDefn *, OGRGeomFieldDefn *>;
769
770
    /** Return an object that can be used to iterate over geometry fields.
771
        \verbatim
772
        for( const auto* poGeomFieldDefn: poFeatureDefn->GetGeomFields() )
773
        {
774
            // do something
775
        }
776
        \endverbatim
777
778
        @since GDAL 3.7
779
     */
780
    inline NonConstGeomFields GetGeomFields()
781
0
    {
782
0
        return NonConstGeomFields(this);
783
0
    }
784
785
    /** Return type of GetGeomFields() const */
786
    using ConstGeomFields =
787
        GeomFields<const OGRFeatureDefn *, const OGRGeomFieldDefn *>;
788
789
    /** Return an object that can be used to iterate over geometry fields.
790
        \verbatim
791
        for( const auto* poGeomFieldDefn: poFeatureDefn->GetGeomFields() )
792
        {
793
            // do something
794
        }
795
        \endverbatim
796
797
        @since GDAL 3.12
798
     */
799
    inline ConstGeomFields GetGeomFields() const
800
2.80M
    {
801
2.80M
        return ConstGeomFields(this);
802
2.80M
    }
803
804
    virtual void AddGeomFieldDefn(const OGRGeomFieldDefn *);
805
    virtual void AddGeomFieldDefn(std::unique_ptr<OGRGeomFieldDefn> &&);
806
    virtual OGRErr DeleteGeomFieldDefn(int iGeomField);
807
808
    virtual OGRwkbGeometryType GetGeomType() const;
809
    virtual void SetGeomType(OGRwkbGeometryType);
810
811
    virtual OGRFeatureDefn *Clone() const;
812
813
    int Reference()
814
126M
    {
815
126M
        return CPLAtomicInc(&nRefCount);
816
126M
    }
817
818
    int Dereference()
819
126M
    {
820
126M
        return CPLAtomicDec(&nRefCount);
821
126M
    }
822
823
    int GetReferenceCount() const
824
0
    {
825
0
        return nRefCount;
826
0
    }
827
828
    void Release();
829
830
    virtual int IsGeometryIgnored() const;
831
    virtual void SetGeometryIgnored(int bIgnore);
832
833
    virtual bool IsStyleIgnored() const
834
0
    {
835
0
        return bIgnoreStyle;
836
0
    }
837
838
    virtual void SetStyleIgnored(bool bIgnore)
839
13.4k
    {
840
13.4k
        bIgnoreStyle = bIgnore;
841
13.4k
    }
842
843
    virtual int IsSame(const OGRFeatureDefn *poOtherFeatureDefn) const;
844
845
    //! @cond Doxygen_Suppress
846
    void ReserveSpaceForFields(int nFieldCountIn);
847
    //! @endcond
848
849
    std::vector<int> ComputeMapForSetFrom(const OGRFeatureDefn *poSrcFDefn,
850
                                          bool bForgiving = true) const;
851
852
    static OGRFeatureDefn *CreateFeatureDefn(const char *pszName = nullptr);
853
    static void DestroyFeatureDefn(OGRFeatureDefn *);
854
855
    /** Convert a OGRFeatureDefn* to a OGRFeatureDefnH.
856
     */
857
    static inline OGRFeatureDefnH ToHandle(OGRFeatureDefn *poFeatureDefn)
858
53.6k
    {
859
53.6k
        return reinterpret_cast<OGRFeatureDefnH>(poFeatureDefn);
860
53.6k
    }
861
862
    /** Convert a OGRFeatureDefnH to a OGRFeatureDefn*.
863
     */
864
    static inline OGRFeatureDefn *FromHandle(OGRFeatureDefnH hFeatureDefn)
865
53.6k
    {
866
53.6k
        return reinterpret_cast<OGRFeatureDefn *>(hFeatureDefn);
867
53.6k
    }
868
869
    void Seal(bool bSealFields);
870
871
    void Unseal(bool bUnsealFields);
872
873
    /*! @cond Doxygen_Suppress */
874
    struct CPL_DLL TemporaryUnsealer
875
    {
876
      private:
877
        OGRFeatureDefn *m_poFeatureDefn = nullptr;
878
        bool m_bSealFields = false;
879
        CPL_DISALLOW_COPY_ASSIGN(TemporaryUnsealer)
880
      public:
881
        explicit TemporaryUnsealer(OGRFeatureDefn *poFeatureDefn,
882
                                   bool bSealFields);
883
884
        TemporaryUnsealer(TemporaryUnsealer &&) = default;
885
        TemporaryUnsealer &operator=(TemporaryUnsealer &&) = default;
886
887
        ~TemporaryUnsealer();
888
889
        OGRFeatureDefn *operator->()
890
1.94M
        {
891
1.94M
            return m_poFeatureDefn;
892
1.94M
        }
893
    };
894
895
    /*! @endcond */
896
897
    TemporaryUnsealer GetTemporaryUnsealer(bool bSealFields = true);
898
899
  private:
900
    CPL_DISALLOW_COPY_ASSIGN(OGRFeatureDefn)
901
};
902
903
#ifdef GDAL_COMPILATION
904
/** Return an object that temporary unseals the OGRFeatureDefn
905
 *
906
 * The returned object calls Unseal() initially, and when it is destroyed
907
 * it calls Seal().
908
 * This method should be called on a OGRFeatureDefn that has been sealed
909
 * previously.
910
 * GetTemporaryUnsealer() calls may be nested, in which case only the first
911
 * one has an effect (similarly to a recursive mutex locked in a nested way
912
 * from the same thread).
913
 *
914
 * This method should only be called by driver implementations.
915
 *
916
 * Usage: whileUnsealing(poFeatureDefn)->some_method();
917
 *
918
 * @param bSealFields Whether fields and geometry fields should be unsealed and
919
 *                    resealed.
920
 *                    This is generally desirable, but in case of deferred
921
 *                    resolution of them, this parameter should be set to false.
922
 * @since GDAL 3.9
923
 */
924
inline OGRFeatureDefn::TemporaryUnsealer whileUnsealing(OGRFeatureDefn *object,
925
                                                        bool bSealFields = true)
926
1.94M
{
927
1.94M
    return object->GetTemporaryUnsealer(bSealFields);
928
1.94M
}
929
#endif
930
931
/************************************************************************/
932
/*                              OGRFeature                              */
933
/************************************************************************/
934
935
/**
936
 * A simple feature, including geometry and attributes.
937
 */
938
939
class CPL_DLL OGRFeature
940
{
941
  private:
942
    GIntBig nFID;
943
    const OGRFeatureDefn *poDefn;
944
    OGRGeometry **papoGeometries;
945
    OGRField *pauFields;
946
    char *m_pszNativeData;
947
    char *m_pszNativeMediaType;
948
949
    bool SetFieldInternal(int i, const OGRField *puValue);
950
951
  protected:
952
    //! @cond Doxygen_Suppress
953
    mutable char *m_pszStyleString;
954
    mutable OGRStyleTable *m_poStyleTable;
955
    mutable char *m_pszTmpFieldValue;
956
    //! @endcond
957
958
    bool CopySelfTo(OGRFeature *poNew) const;
959
960
  public:
961
    explicit OGRFeature(const OGRFeatureDefn *);
962
    virtual ~OGRFeature();
963
964
    /** Field value. */
965
    class CPL_DLL FieldValue
966
    {
967
        friend class OGRFeature;
968
        struct Private;
969
        std::unique_ptr<Private> m_poPrivate;
970
971
        FieldValue(OGRFeature *poFeature, int iFieldIndex);
972
        FieldValue(const OGRFeature *poFeature, int iFieldIndex);
973
        FieldValue(const FieldValue &oOther) = delete;
974
        FieldValue &Assign(const FieldValue &oOther);
975
976
      public:
977
        //! @cond Doxygen_Suppress
978
        ~FieldValue();
979
980
        FieldValue &operator=(FieldValue &&oOther);
981
        //! @endcond
982
983
        /** Set a field value from another one. */
984
        FieldValue &operator=(const FieldValue &oOther);
985
        /** Set an integer value to the field. */
986
        FieldValue &operator=(int nVal);
987
        /** Set an integer value to the field. */
988
        FieldValue &operator=(GIntBig nVal);
989
        /** Set a real value to the field. */
990
        FieldValue &operator=(double dfVal);
991
        /** Set a string value to the field. */
992
        FieldValue &operator=(const char *pszVal);
993
        /** Set a string value to the field. */
994
        FieldValue &operator=(const std::string &osVal);
995
        /** Set an array of integer to the field. */
996
        FieldValue &operator=(const std::vector<int> &oArray);
997
        /** Set an array of big integer to the field. */
998
        FieldValue &operator=(const std::vector<GIntBig> &oArray);
999
        /** Set an array of double to the field. */
1000
        FieldValue &operator=(const std::vector<double> &oArray);
1001
        /** Set an array of strings to the field. */
1002
        FieldValue &operator=(const std::vector<std::string> &oArray);
1003
        /** Set an array of strings to the field. */
1004
        FieldValue &operator=(CSLConstList papszValues);
1005
        /** Set a null value to the field. */
1006
        void SetNull();
1007
        /** Unset the field. */
1008
        void clear();
1009
1010
        /** Unset the field. */
1011
        void Unset()
1012
0
        {
1013
0
            clear();
1014
0
        }
1015
1016
        /** Set date time value/ */
1017
        void SetDateTime(int nYear, int nMonth, int nDay, int nHour = 0,
1018
                         int nMinute = 0, float fSecond = 0.f, int nTZFlag = 0);
1019
1020
        /** Return field index. */
1021
        int GetIndex() const;
1022
        /** Return field definition. */
1023
        const OGRFieldDefn *GetDefn() const;
1024
1025
        /** Return field name. */
1026
        const char *GetName() const
1027
0
        {
1028
0
            return GetDefn()->GetNameRef();
1029
0
        }
1030
1031
        /** Return field type. */
1032
        OGRFieldType GetType() const
1033
0
        {
1034
0
            return GetDefn()->GetType();
1035
0
        }
1036
1037
        /** Return field subtype. */
1038
        OGRFieldSubType GetSubType() const
1039
0
        {
1040
0
            return GetDefn()->GetSubType();
1041
0
        }
1042
1043
        /** Return whether the field value is unset/empty. */
1044
        // cppcheck-suppress functionStatic
1045
        bool empty() const
1046
0
        {
1047
0
            return IsUnset();
1048
0
        }
1049
1050
        /** Return whether the field value is unset/empty. */
1051
        // cppcheck-suppress functionStatic
1052
        bool IsUnset() const;
1053
1054
        /** Return whether the field value is null. */
1055
        // cppcheck-suppress functionStatic
1056
        bool IsNull() const;
1057
1058
        /** Return the raw field value */
1059
        const OGRField *GetRawValue() const;
1060
1061
        /** Return the integer value.
1062
         * Only use that method if and only if GetType() == OFTInteger.
1063
         */
1064
        // cppcheck-suppress functionStatic
1065
        int GetInteger() const
1066
0
        {
1067
0
            return GetRawValue()->Integer;
1068
0
        }
1069
1070
        /** Return the 64-bit integer value.
1071
         * Only use that method if and only if GetType() == OFTInteger64.
1072
         */
1073
        // cppcheck-suppress functionStatic
1074
        GIntBig GetInteger64() const
1075
0
        {
1076
0
            return GetRawValue()->Integer64;
1077
0
        }
1078
1079
        /** Return the double value.
1080
         * Only use that method if and only if GetType() == OFTReal.
1081
         */
1082
        // cppcheck-suppress functionStatic
1083
        double GetDouble() const
1084
0
        {
1085
0
            return GetRawValue()->Real;
1086
0
        }
1087
1088
        /** Return the string value.
1089
         * Only use that method if and only if GetType() == OFTString.
1090
         */
1091
        // cppcheck-suppress functionStatic
1092
        const char *GetString() const
1093
0
        {
1094
0
            return GetRawValue()->String;
1095
0
        }
1096
1097
        /** Return the date/time/datetime value. */
1098
        bool GetDateTime(int *pnYear, int *pnMonth, int *pnDay, int *pnHour,
1099
                         int *pnMinute, float *pfSecond, int *pnTZFlag) const;
1100
1101
        /** Return the field value as integer, with potential conversion */
1102
        operator int() const
1103
0
        {
1104
0
            return GetAsInteger();
1105
0
        }
1106
1107
        /** Return the field value as 64-bit integer, with potential conversion
1108
         */
1109
        operator GIntBig() const
1110
0
        {
1111
0
            return GetAsInteger64();
1112
0
        }
1113
1114
        /** Return the field value as double, with potential conversion */
1115
        operator double() const
1116
0
        {
1117
0
            return GetAsDouble();
1118
0
        }
1119
1120
        /** Return the field value as string, with potential conversion */
1121
        operator const char *() const
1122
0
        {
1123
0
            return GetAsString();
1124
0
        }
1125
1126
        /** Return the field value as integer list, with potential conversion */
1127
        operator const std::vector<int> &() const
1128
0
        {
1129
0
            return GetAsIntegerList();
1130
0
        }
1131
1132
        /** Return the field value as 64-bit integer list, with potential
1133
         * conversion */
1134
        operator const std::vector<GIntBig> &() const
1135
0
        {
1136
0
            return GetAsInteger64List();
1137
0
        }
1138
1139
        /** Return the field value as double list, with potential conversion */
1140
        operator const std::vector<double> &() const
1141
0
        {
1142
0
            return GetAsDoubleList();
1143
0
        }
1144
1145
        /** Return the field value as string list, with potential conversion */
1146
        operator const std::vector<std::string> &() const
1147
0
        {
1148
0
            return GetAsStringList();
1149
0
        }
1150
1151
        /** Return the field value as string list, with potential conversion */
1152
        operator CSLConstList() const;
1153
1154
        /** Return the field value as integer, with potential conversion */
1155
        int GetAsInteger() const;
1156
        /** Return the field value as 64-bit integer, with potential conversion
1157
         */
1158
        GIntBig GetAsInteger64() const;
1159
        /** Return the field value as double, with potential conversion */
1160
        double GetAsDouble() const;
1161
        /** Return the field value as string, with potential conversion */
1162
        const char *GetAsString() const;
1163
        /** Return the field value as integer list, with potential conversion */
1164
        const std::vector<int> &GetAsIntegerList() const;
1165
        /** Return the field value as 64-bit integer list, with potential
1166
         * conversion */
1167
        const std::vector<GIntBig> &GetAsInteger64List() const;
1168
        /** Return the field value as double list, with potential conversion */
1169
        const std::vector<double> &GetAsDoubleList() const;
1170
        /** Return the field value as string list, with potential conversion */
1171
        const std::vector<std::string> &GetAsStringList() const;
1172
    };
1173
1174
    /** Field value iterator class. */
1175
    class CPL_DLL ConstFieldIterator
1176
    {
1177
        friend class OGRFeature;
1178
        struct Private;
1179
        std::unique_ptr<Private> m_poPrivate;
1180
1181
        ConstFieldIterator(const OGRFeature *poSelf, int nPos);
1182
1183
      public:
1184
        //! @cond Doxygen_Suppress
1185
        ConstFieldIterator(
1186
            ConstFieldIterator &&oOther) noexcept;  // declared but not defined.
1187
        // Needed for gcc 5.4 at least
1188
        ~ConstFieldIterator();
1189
        const FieldValue &operator*() const;
1190
        ConstFieldIterator &operator++();
1191
        bool operator!=(const ConstFieldIterator &it) const;
1192
        //! @endcond
1193
    };
1194
1195
    /** Return begin of field value iterator.
1196
     *
1197
     * Using this iterator for standard range-based loops is safe, but
1198
     * due to implementation limitations, you shouldn't try to access
1199
     * (dereference) more than one iterator step at a time, since you will get
1200
     * a reference to the same object (FieldValue) at each iteration step.
1201
     *
1202
     * \code{.cpp}
1203
     * for( auto&& oField: poFeature )
1204
     * {
1205
     *      std::cout << oField.GetIndex() << "," << oField.GetName()<< ": " <<
1206
     * oField.GetAsString() << std::endl;
1207
     * }
1208
     * \endcode
1209
     *
1210
     */
1211
    ConstFieldIterator begin() const;
1212
    /** Return end of field value iterator. */
1213
    ConstFieldIterator end() const;
1214
1215
    const FieldValue operator[](int iField) const;
1216
    FieldValue operator[](int iField);
1217
1218
#if defined(__clang__)
1219
#pragma clang diagnostic push
1220
#pragma clang diagnostic ignored "-Wweak-vtables"
1221
#endif
1222
1223
    /** Exception raised by operator[](const char*) when a field is not found.
1224
     */
1225
    class FieldNotFoundException final : public std::exception
1226
    {
1227
    };
1228
1229
#if defined(__clang__)
1230
#pragma clang diagnostic pop
1231
#endif
1232
1233
    const FieldValue operator[](const char *pszFieldName) const;
1234
    FieldValue operator[](const char *pszFieldName);
1235
1236
    const OGRFeatureDefn *GetDefnRef() const
1237
29.3M
    {
1238
29.3M
        return poDefn;
1239
29.3M
    }
1240
1241
    //! @cond Doxygen_Suppress
1242
    void SetFDefnUnsafe(OGRFeatureDefn *poNewFDefn);
1243
    //! @endcond
1244
1245
    OGRErr SetGeometryDirectly(OGRGeometry *);
1246
    OGRErr SetGeometry(const OGRGeometry *);
1247
    OGRErr SetGeometry(std::unique_ptr<OGRGeometry>);
1248
    OGRGeometry *GetGeometryRef();
1249
    const OGRGeometry *GetGeometryRef() const;
1250
    OGRGeometry *StealGeometry() CPL_WARN_UNUSED_RESULT;
1251
1252
    int GetGeomFieldCount() const
1253
153M
    {
1254
153M
        return poDefn->GetGeomFieldCount();
1255
153M
    }
1256
1257
    const OGRGeomFieldDefn *GetGeomFieldDefnRef(int iField) const
1258
2.75M
    {
1259
2.75M
        return poDefn->GetGeomFieldDefn(iField);
1260
2.75M
    }
1261
1262
    int GetGeomFieldIndex(const char *pszName) const
1263
2.74M
    {
1264
2.74M
        return poDefn->GetGeomFieldIndex(pszName);
1265
2.74M
    }
1266
1267
    OGRGeometry *GetGeomFieldRef(int iField);
1268
    const OGRGeometry *GetGeomFieldRef(int iField) const;
1269
    OGRGeometry *StealGeometry(int iField);
1270
    OGRGeometry *GetGeomFieldRef(const char *pszFName);
1271
    const OGRGeometry *GetGeomFieldRef(const char *pszFName) const;
1272
    OGRErr SetGeomFieldDirectly(int iField, OGRGeometry *);
1273
    OGRErr SetGeomField(int iField, const OGRGeometry *);
1274
    OGRErr SetGeomField(int iField, std::unique_ptr<OGRGeometry>);
1275
1276
    void Reset();
1277
1278
    OGRFeature *Clone() const CPL_WARN_UNUSED_RESULT;
1279
    virtual OGRBoolean Equal(const OGRFeature *poFeature) const;
1280
1281
    int GetFieldCount() const
1282
33.1M
    {
1283
33.1M
        return poDefn->GetFieldCount();
1284
33.1M
    }
1285
1286
    const OGRFieldDefn *GetFieldDefnRef(int iField) const
1287
17.9M
    {
1288
17.9M
        return poDefn->GetFieldDefn(iField);
1289
17.9M
    }
1290
1291
    int GetFieldIndex(const char *pszName) const
1292
86.5M
    {
1293
86.5M
        return poDefn->GetFieldIndex(pszName);
1294
86.5M
    }
1295
1296
    int IsFieldSet(int iField) const;
1297
1298
    void UnsetField(int iField);
1299
1300
    bool IsFieldNull(int iField) const;
1301
1302
    void SetFieldNull(int iField);
1303
1304
    bool IsFieldSetAndNotNull(int iField) const;
1305
1306
    OGRField *GetRawFieldRef(int i)
1307
5.49M
    {
1308
5.49M
        return pauFields + i;
1309
5.49M
    }
1310
1311
    const OGRField *GetRawFieldRef(int i) const
1312
0
    {
1313
0
        return pauFields + i;
1314
0
    }
1315
1316
    int GetFieldAsInteger(int i) const;
1317
    GIntBig GetFieldAsInteger64(int i) const;
1318
    double GetFieldAsDouble(int i) const;
1319
    const char *GetFieldAsString(int i) const;
1320
    const char *GetFieldAsISO8601DateTime(int i,
1321
                                          CSLConstList papszOptions) const;
1322
    const int *GetFieldAsIntegerList(int i, int *pnCount) const;
1323
    const GIntBig *GetFieldAsInteger64List(int i, int *pnCount) const;
1324
    const double *GetFieldAsDoubleList(int i, int *pnCount) const;
1325
    char **GetFieldAsStringList(int i) const;
1326
    GByte *GetFieldAsBinary(int i, int *pnCount) const;
1327
    int GetFieldAsDateTime(int i, int *pnYear, int *pnMonth, int *pnDay,
1328
                           int *pnHour, int *pnMinute, int *pnSecond,
1329
                           int *pnTZFlag) const;
1330
    int GetFieldAsDateTime(int i, int *pnYear, int *pnMonth, int *pnDay,
1331
                           int *pnHour, int *pnMinute, float *pfSecond,
1332
                           int *pnTZFlag) const;
1333
    char *GetFieldAsSerializedJSon(int i) const;
1334
1335
    //! @cond Doxygen_Suppress
1336
    bool IsFieldSetUnsafe(int i) const
1337
1.09G
    {
1338
1.09G
        return !(pauFields[i].Set.nMarker1 == OGRUnsetMarker &&
1339
871M
                 pauFields[i].Set.nMarker2 == OGRUnsetMarker &&
1340
871M
                 pauFields[i].Set.nMarker3 == OGRUnsetMarker);
1341
1.09G
    }
1342
1343
    bool IsFieldNullUnsafe(int i) const
1344
225M
    {
1345
225M
        return (pauFields[i].Set.nMarker1 == OGRNullMarker &&
1346
414k
                pauFields[i].Set.nMarker2 == OGRNullMarker &&
1347
379k
                pauFields[i].Set.nMarker3 == OGRNullMarker);
1348
225M
    }
1349
1350
    bool IsFieldSetAndNotNullUnsafe(int i) const
1351
1.06G
    {
1352
1.06G
        return IsFieldSetUnsafe(i) && !IsFieldNullUnsafe(i);
1353
1.06G
    }
1354
1355
    // Those methods should only be called on a field that is of the type
1356
    // consistent with the value, and that is set.
1357
    int GetFieldAsIntegerUnsafe(int i) const
1358
16.5k
    {
1359
16.5k
        return pauFields[i].Integer;
1360
16.5k
    }
1361
1362
    GIntBig GetFieldAsInteger64Unsafe(int i) const
1363
357
    {
1364
357
        return pauFields[i].Integer64;
1365
357
    }
1366
1367
    double GetFieldAsDoubleUnsafe(int i) const
1368
20.0k
    {
1369
20.0k
        return pauFields[i].Real;
1370
20.0k
    }
1371
1372
    const char *GetFieldAsStringUnsafe(int i) const
1373
5.44M
    {
1374
5.44M
        return pauFields[i].String;
1375
5.44M
    }
1376
1377
    //! @endcond
1378
1379
    int GetFieldAsInteger(const char *pszFName) const
1380
17.8M
    {
1381
17.8M
        return GetFieldAsInteger(GetFieldIndex(pszFName));
1382
17.8M
    }
1383
1384
    GIntBig GetFieldAsInteger64(const char *pszFName) const
1385
0
    {
1386
0
        return GetFieldAsInteger64(GetFieldIndex(pszFName));
1387
0
    }
1388
1389
    double GetFieldAsDouble(const char *pszFName) const
1390
0
    {
1391
0
        return GetFieldAsDouble(GetFieldIndex(pszFName));
1392
0
    }
1393
1394
    const char *GetFieldAsString(const char *pszFName) const
1395
36.5M
    {
1396
36.5M
        return GetFieldAsString(GetFieldIndex(pszFName));
1397
36.5M
    }
1398
1399
    const char *GetFieldAsISO8601DateTime(const char *pszFName,
1400
                                          CSLConstList papszOptions) const
1401
0
    {
1402
0
        return GetFieldAsISO8601DateTime(GetFieldIndex(pszFName), papszOptions);
1403
0
    }
1404
1405
    const int *GetFieldAsIntegerList(const char *pszFName, int *pnCount) const
1406
0
    {
1407
0
        return GetFieldAsIntegerList(GetFieldIndex(pszFName), pnCount);
1408
0
    }
1409
1410
    const GIntBig *GetFieldAsInteger64List(const char *pszFName,
1411
                                           int *pnCount) const
1412
0
    {
1413
0
        return GetFieldAsInteger64List(GetFieldIndex(pszFName), pnCount);
1414
0
    }
1415
1416
    const double *GetFieldAsDoubleList(const char *pszFName, int *pnCount) const
1417
0
    {
1418
0
        return GetFieldAsDoubleList(GetFieldIndex(pszFName), pnCount);
1419
0
    }
1420
1421
    char **GetFieldAsStringList(const char *pszFName) const
1422
0
    {
1423
0
        return GetFieldAsStringList(GetFieldIndex(pszFName));
1424
0
    }
1425
1426
    void SetField(int i, int nValue);
1427
    void SetField(int i, GIntBig nValue);
1428
    void SetField(int i, double dfValue);
1429
    void SetField(int i, const char *pszValue);
1430
    void SetField(int i, int nCount, const int *panValues);
1431
    void SetField(int i, int nCount, const GIntBig *panValues);
1432
    void SetField(int i, int nCount, const double *padfValues);
1433
    void SetField(int i, const char *const *papszValues);
1434
    void SetField(int i, const OGRField *puValue);
1435
    void SetField(int i, int nCount, const void *pabyBinary);
1436
    void SetField(int i, int nYear, int nMonth, int nDay, int nHour = 0,
1437
                  int nMinute = 0, float fSecond = 0.f, int nTZFlag = 0);
1438
1439
    //! @cond Doxygen_Suppress
1440
    // Those methods should only be called on a field that is of the type
1441
    // consistent with the value, and in a unset state.
1442
    void SetFieldSameTypeUnsafe(int i, int nValue)
1443
308k
    {
1444
308k
        pauFields[i].Integer = nValue;
1445
308k
        pauFields[i].Set.nMarker2 = 0;
1446
308k
        pauFields[i].Set.nMarker3 = 0;
1447
308k
    }
1448
1449
    void SetFieldSameTypeUnsafe(int i, GIntBig nValue)
1450
6.68k
    {
1451
6.68k
        pauFields[i].Integer64 = nValue;
1452
6.68k
    }
1453
1454
    void SetFieldSameTypeUnsafe(int i, double dfValue)
1455
18.7k
    {
1456
18.7k
        pauFields[i].Real = dfValue;
1457
18.7k
    }
1458
1459
    void SetFieldSameTypeUnsafe(int i, char *pszValueTransferred)
1460
4.91M
    {
1461
4.91M
        pauFields[i].String = pszValueTransferred;
1462
4.91M
    }
1463
1464
    //! @endcond
1465
1466
    void SetField(const char *pszFName, int nValue)
1467
18.4M
    {
1468
18.4M
        SetField(GetFieldIndex(pszFName), nValue);
1469
18.4M
    }
1470
1471
    void SetField(const char *pszFName, GIntBig nValue)
1472
76
    {
1473
76
        SetField(GetFieldIndex(pszFName), nValue);
1474
76
    }
1475
1476
    void SetField(const char *pszFName, double dfValue)
1477
10.9k
    {
1478
10.9k
        SetField(GetFieldIndex(pszFName), dfValue);
1479
10.9k
    }
1480
1481
    void SetField(const char *pszFName, const char *pszValue)
1482
1.74M
    {
1483
1.74M
        SetField(GetFieldIndex(pszFName), pszValue);
1484
1.74M
    }
1485
1486
    void SetField(const char *pszFName, int nCount, const int *panValues)
1487
0
    {
1488
0
        SetField(GetFieldIndex(pszFName), nCount, panValues);
1489
0
    }
1490
1491
    void SetField(const char *pszFName, int nCount, const GIntBig *panValues)
1492
0
    {
1493
0
        SetField(GetFieldIndex(pszFName), nCount, panValues);
1494
0
    }
1495
1496
    void SetField(const char *pszFName, int nCount, const double *padfValues)
1497
0
    {
1498
0
        SetField(GetFieldIndex(pszFName), nCount, padfValues);
1499
0
    }
1500
1501
    void SetField(const char *pszFName, const char *const *papszValues)
1502
0
    {
1503
0
        SetField(GetFieldIndex(pszFName), papszValues);
1504
0
    }
1505
1506
    void SetField(const char *pszFName, const OGRField *puValue)
1507
0
    {
1508
0
        SetField(GetFieldIndex(pszFName), puValue);
1509
0
    }
1510
1511
    void SetField(const char *pszFName, int nYear, int nMonth, int nDay,
1512
                  int nHour = 0, int nMinute = 0, float fSecond = 0.f,
1513
                  int nTZFlag = 0)
1514
0
    {
1515
0
        SetField(GetFieldIndex(pszFName), nYear, nMonth, nDay, nHour, nMinute,
1516
0
                 fSecond, nTZFlag);
1517
0
    }
1518
1519
    GIntBig GetFID() const
1520
254M
    {
1521
254M
        return nFID;
1522
254M
    }
1523
1524
    virtual OGRErr SetFID(GIntBig nFIDIn);
1525
1526
    void DumpReadable(FILE *, CSLConstList papszOptions = nullptr) const;
1527
    std::string DumpReadableAsString(CSLConstList papszOptions = nullptr) const;
1528
1529
    OGRErr SetFrom(const OGRFeature *, int bForgiving = TRUE);
1530
    OGRErr SetFrom(const OGRFeature *, const int *panMap, int bForgiving = TRUE,
1531
                   bool bUseISO8601ForDateTimeAsString = false);
1532
    OGRErr SetFieldsFrom(const OGRFeature *, const int *panMap,
1533
                         int bForgiving = TRUE,
1534
                         bool bUseISO8601ForDateTimeAsString = false);
1535
1536
    //! @cond Doxygen_Suppress
1537
    OGRErr RemapFields(const OGRFeatureDefn *poNewDefn,
1538
                       const int *panRemapSource);
1539
    void AppendField();
1540
    OGRErr RemapGeomFields(const OGRFeatureDefn *poNewDefn,
1541
                           const int *panRemapSource);
1542
    //! @endcond
1543
1544
    int Validate(int nValidateFlags, int bEmitError) const;
1545
    void FillUnsetWithDefault(int bNotNullableOnly, CSLConstList papszOptions);
1546
1547
    bool SerializeToBinary(std::vector<GByte> &abyBuffer) const;
1548
    bool DeserializeFromBinary(const GByte *pabyBuffer, size_t nSize);
1549
1550
    virtual const char *GetStyleString() const;
1551
    virtual void SetStyleString(const char *);
1552
    virtual void SetStyleStringDirectly(char *);
1553
1554
    /** Return style table.
1555
     * @return style table.
1556
     */
1557
    virtual OGRStyleTable *GetStyleTable() const
1558
0
    {
1559
0
        return m_poStyleTable;
1560
0
    } /* f.i.x.m.e: add a const qualifier for return type */
1561
1562
    virtual void SetStyleTable(OGRStyleTable *poStyleTable);
1563
    virtual void SetStyleTableDirectly(OGRStyleTable *poStyleTable);
1564
1565
    const char *GetNativeData() const
1566
4.42M
    {
1567
4.42M
        return m_pszNativeData;
1568
4.42M
    }
1569
1570
    const char *GetNativeMediaType() const
1571
5.08M
    {
1572
5.08M
        return m_pszNativeMediaType;
1573
5.08M
    }
1574
1575
    void SetNativeData(const char *pszNativeData);
1576
    void SetNativeMediaType(const char *pszNativeMediaType);
1577
1578
    static OGRFeature *CreateFeature(const OGRFeatureDefn *);
1579
    static void DestroyFeature(OGRFeature *);
1580
1581
    /** Convert a OGRFeature* to a OGRFeatureH.
1582
     */
1583
    static inline OGRFeatureH ToHandle(OGRFeature *poFeature)
1584
11.9M
    {
1585
11.9M
        return reinterpret_cast<OGRFeatureH>(poFeature);
1586
11.9M
    }
1587
1588
    /** Convert a OGRFeatureH to a OGRFeature*.
1589
     */
1590
    static inline OGRFeature *FromHandle(OGRFeatureH hFeature)
1591
13.7M
    {
1592
13.7M
        return reinterpret_cast<OGRFeature *>(hFeature);
1593
13.7M
    }
1594
1595
  private:
1596
    CPL_DISALLOW_COPY_ASSIGN(OGRFeature)
1597
};
1598
1599
//! @cond Doxygen_Suppress
1600
struct CPL_DLL OGRFeatureUniquePtrDeleter
1601
{
1602
    void operator()(OGRFeature *) const;
1603
};
1604
1605
//! @endcond
1606
1607
/** Unique pointer type for OGRFeature.
1608
 */
1609
typedef std::unique_ptr<OGRFeature, OGRFeatureUniquePtrDeleter>
1610
    OGRFeatureUniquePtr;
1611
1612
//! @cond Doxygen_Suppress
1613
/** @see OGRFeature::begin() const */
1614
inline OGRFeature::ConstFieldIterator begin(const OGRFeature *poFeature)
1615
0
{
1616
0
    return poFeature->begin();
1617
0
}
1618
1619
/** @see OGRFeature::end() const */
1620
inline OGRFeature::ConstFieldIterator end(const OGRFeature *poFeature)
1621
0
{
1622
0
    return poFeature->end();
1623
0
}
1624
1625
/** @see OGRFeature::begin() const */
1626
inline OGRFeature::ConstFieldIterator
1627
begin(const OGRFeatureUniquePtr &poFeature)
1628
0
{
1629
0
    return poFeature->begin();
1630
0
}
1631
1632
/** @see OGRFeature::end() const */
1633
inline OGRFeature::ConstFieldIterator end(const OGRFeatureUniquePtr &poFeature)
1634
0
{
1635
0
    return poFeature->end();
1636
0
}
1637
1638
//! @endcond
1639
1640
/************************************************************************/
1641
/*                            OGRFieldDomain                            */
1642
/************************************************************************/
1643
1644
/* clang-format off */
1645
/**
1646
 * Definition of a field domain.
1647
 *
1648
 * A field domain is a set of constraints that apply to one or several fields.
1649
 *
1650
 * This is a concept found in
1651
 * <a href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/geodatabases/an-overview-of-attribute-domains.htm">File
1652
 * Geodatabase</a> or GeoPackage (using the <a href="http://www.geopackage.org/spec/#extension_schema">schema extension</a>)
1653
 * for example.
1654
 *
1655
 * A field domain can be:
1656
 * <ul>
1657
 * <li>OGRCodedFieldDomain: an enumerated list of (code, value) tuples.</li>
1658
 * <li>OGRRangeFieldDomain: a range constraint (min, max).</li>
1659
 * <li>OGRGlobFieldDomain: a glob expression.</li>
1660
 * </ul>
1661
 *
1662
 * @since GDAL 3.3
1663
 */
1664
/* clang-format on */
1665
1666
class CPL_DLL OGRFieldDomain
1667
{
1668
  protected:
1669
    /*! @cond Doxygen_Suppress */
1670
    std::string m_osName;
1671
    std::string m_osDescription;
1672
    OGRFieldDomainType m_eDomainType;
1673
    OGRFieldType m_eFieldType;
1674
    OGRFieldSubType m_eFieldSubType;
1675
    OGRFieldDomainSplitPolicy m_eSplitPolicy = OFDSP_DEFAULT_VALUE;
1676
    OGRFieldDomainMergePolicy m_eMergePolicy = OFDMP_DEFAULT_VALUE;
1677
1678
    OGRFieldDomain(const std::string &osName, const std::string &osDescription,
1679
                   OGRFieldDomainType eDomainType, OGRFieldType eFieldType,
1680
                   OGRFieldSubType eFieldSubType);
1681
    /*! @endcond */
1682
1683
  public:
1684
    /** Destructor.
1685
     *
1686
     * This is the same as the C function OGR_FldDomain_Destroy().
1687
     */
1688
    virtual ~OGRFieldDomain();
1689
1690
    /** Clone.
1691
     *
1692
     * Return a cloned object, or nullptr in case of error.
1693
     */
1694
    virtual OGRFieldDomain *Clone() const = 0;
1695
1696
    /** Get the name of the field domain.
1697
     *
1698
     * This is the same as the C function OGR_FldDomain_GetName().
1699
     */
1700
    const std::string &GetName() const
1701
0
    {
1702
0
        return m_osName;
1703
0
    }
1704
1705
    /** Get the description of the field domain.
1706
     * Empty string if there is none.
1707
     *
1708
     * This is the same as the C function OGR_FldDomain_GetDescription().
1709
     */
1710
    const std::string &GetDescription() const
1711
0
    {
1712
0
        return m_osDescription;
1713
0
    }
1714
1715
    /** Get the type of the field domain.
1716
     *
1717
     * This is the same as the C function OGR_FldDomain_GetDomainType().
1718
     */
1719
    OGRFieldDomainType GetDomainType() const
1720
0
    {
1721
0
        return m_eDomainType;
1722
0
    }
1723
1724
    /** Get the field type.
1725
     *
1726
     * This is the same as the C function OGR_FldDomain_GetFieldType().
1727
     */
1728
    OGRFieldType GetFieldType() const
1729
0
    {
1730
0
        return m_eFieldType;
1731
0
    }
1732
1733
    /** Get the field subtype.
1734
     *
1735
     * This is the same as the C function OGR_FldDomain_GetFieldSubType().
1736
     */
1737
    OGRFieldSubType GetFieldSubType() const
1738
0
    {
1739
0
        return m_eFieldSubType;
1740
0
    }
1741
1742
    /** Convert a OGRFieldDomain* to a OGRFieldDomainH. */
1743
    static inline OGRFieldDomainH ToHandle(OGRFieldDomain *poFieldDomain)
1744
0
    {
1745
0
        return reinterpret_cast<OGRFieldDomainH>(poFieldDomain);
1746
0
    }
1747
1748
    /** Convert a OGRFieldDomainH to a OGRFieldDomain*. */
1749
    static inline OGRFieldDomain *FromHandle(OGRFieldDomainH hFieldDomain)
1750
0
    {
1751
0
        return reinterpret_cast<OGRFieldDomain *>(hFieldDomain);
1752
0
    }
1753
1754
    /** Get the split policy.
1755
     *
1756
     * This is the same as the C function OGR_FldDomain_GetSplitPolicy().
1757
     */
1758
    OGRFieldDomainSplitPolicy GetSplitPolicy() const
1759
0
    {
1760
0
        return m_eSplitPolicy;
1761
0
    }
1762
1763
    /** Set the split policy.
1764
     *
1765
     * This is the same as the C function OGR_FldDomain_SetSplitPolicy().
1766
     */
1767
    void SetSplitPolicy(OGRFieldDomainSplitPolicy policy)
1768
0
    {
1769
0
        m_eSplitPolicy = policy;
1770
0
    }
1771
1772
    /** Get the merge policy.
1773
     *
1774
     * This is the same as the C function OGR_FldDomain_GetMergePolicy().
1775
     */
1776
    OGRFieldDomainMergePolicy GetMergePolicy() const
1777
0
    {
1778
0
        return m_eMergePolicy;
1779
0
    }
1780
1781
    /** Set the merge policy.
1782
     *
1783
     * This is the same as the C function OGR_FldDomain_SetMergePolicy().
1784
     */
1785
    void SetMergePolicy(OGRFieldDomainMergePolicy policy)
1786
0
    {
1787
0
        m_eMergePolicy = policy;
1788
0
    }
1789
};
1790
1791
/** Definition of a coded / enumerated field domain.
1792
 *
1793
 * A code field domain is a domain for which only a limited set of codes,
1794
 * associated with their expanded value, are allowed.
1795
 * The type of the code should be the one of the field domain.
1796
 */
1797
class CPL_DLL OGRCodedFieldDomain final : public OGRFieldDomain
1798
{
1799
  private:
1800
    std::vector<OGRCodedValue> m_asValues{};
1801
1802
    OGRCodedFieldDomain(const OGRCodedFieldDomain &) = delete;
1803
    OGRCodedFieldDomain &operator=(const OGRCodedFieldDomain &) = delete;
1804
1805
  public:
1806
    /** Constructor.
1807
     *
1808
     * This is the same as the C function OGR_CodedFldDomain_Create()
1809
     * (except that the C function copies the enumeration, whereas the C++
1810
     * method moves it)
1811
     *
1812
     * @param osName         Domain name.
1813
     * @param osDescription  Domain description.
1814
     * @param eFieldType     Field type. Generally numeric. Potentially
1815
     * OFTDateTime
1816
     * @param eFieldSubType  Field subtype.
1817
     * @param asValues       Enumeration as (code, value) pairs.
1818
     *                       Each code should appear only once, but it is the
1819
     *                       responsibility of the user to check it.
1820
     */
1821
    OGRCodedFieldDomain(const std::string &osName,
1822
                        const std::string &osDescription,
1823
                        OGRFieldType eFieldType, OGRFieldSubType eFieldSubType,
1824
                        std::vector<OGRCodedValue> &&asValues);
1825
1826
    ~OGRCodedFieldDomain() override;
1827
1828
    OGRCodedFieldDomain *Clone() const override;
1829
1830
    /** Get the enumeration as (code, value) pairs.
1831
     * The end of the enumeration is signaled by code == NULL.
1832
     *
1833
     * This is the same as the C function OGR_CodedFldDomain_GetEnumeration().
1834
     */
1835
    const OGRCodedValue *GetEnumeration() const
1836
0
    {
1837
0
        return m_asValues.data();
1838
0
    }
1839
};
1840
1841
/** Definition of a numeric field domain with a range of validity for values.
1842
 */
1843
class CPL_DLL OGRRangeFieldDomain final : public OGRFieldDomain
1844
{
1845
  private:
1846
    OGRField m_sMin;
1847
    OGRField m_sMax;
1848
    bool m_bMinIsInclusive;
1849
    bool m_bMaxIsInclusive;
1850
1851
    OGRRangeFieldDomain(const OGRRangeFieldDomain &) = delete;
1852
    OGRRangeFieldDomain &operator=(const OGRRangeFieldDomain &) = delete;
1853
1854
  public:
1855
    /** Constructor.
1856
     *
1857
     * This is the same as the C function OGR_RangeFldDomain_Create().
1858
     *
1859
     * @param osName          Domain name.
1860
     * @param osDescription   Domain description.
1861
     * @param eFieldType      Field type.
1862
     *                        One among OFTInteger, OFTInteger64, OFTReal or
1863
     * OFTDateTime
1864
     * @param eFieldSubType   Field subtype.
1865
     * @param sMin            Minimum value.
1866
     *                        Which member in the OGRField enum must be read
1867
     *                        depends on the field type.
1868
     *                        If no minimum is set (might not be supported by
1869
     *                        all backends), then initialize the value with
1870
     *                        OGR_RawField_SetUnset().
1871
     * @param bMinIsInclusive Whether the minimum value is included in the
1872
     * range.
1873
     * @param sMax            Minimum value.
1874
     *                        Which member in the OGRField enum must be read
1875
     *                        depends on the field type.
1876
     *                        If no maximum is set (might not be supported by
1877
     *                        all backends), then initialize the value with
1878
     *                        OGR_RawField_SetUnset().
1879
     * @param bMaxIsInclusive Whether the minimum value is included in the
1880
     * range.
1881
     */
1882
    OGRRangeFieldDomain(const std::string &osName,
1883
                        const std::string &osDescription,
1884
                        OGRFieldType eFieldType, OGRFieldSubType eFieldSubType,
1885
                        const OGRField &sMin, bool bMinIsInclusive,
1886
                        const OGRField &sMax, bool bMaxIsInclusive);
1887
1888
    OGRRangeFieldDomain *Clone() const override;
1889
1890
    /** Get the minimum value.
1891
     *
1892
     * Which member in the returned OGRField enum must be read depends on the
1893
     * field type.
1894
     *
1895
     * If no minimum value is set, the OGR_RawField_IsUnset() will return true
1896
     * when called on the result.
1897
     *
1898
     * This is the same as the C function OGR_RangeFldDomain_GetMin().
1899
     *
1900
     * @param bIsInclusiveOut set to true if the minimum is included in the
1901
     * range.
1902
     */
1903
    const OGRField &GetMin(bool &bIsInclusiveOut) const
1904
0
    {
1905
0
        bIsInclusiveOut = m_bMinIsInclusive;
1906
0
        return m_sMin;
1907
0
    }
1908
1909
    /** Get the maximum value.
1910
     *
1911
     * Which member in the returned OGRField enum must be read depends on the
1912
     * field type.
1913
     *
1914
     * If no maximum value is set, the OGR_RawField_IsUnset() will return true
1915
     * when called on the result.
1916
     *
1917
     * This is the same as the C function OGR_RangeFldDomain_GetMax().
1918
     *
1919
     * @param bIsInclusiveOut set to true if the maximum is included in the
1920
     * range.
1921
     */
1922
    const OGRField &GetMax(bool &bIsInclusiveOut) const
1923
0
    {
1924
0
        bIsInclusiveOut = m_bMaxIsInclusive;
1925
0
        return m_sMax;
1926
0
    }
1927
};
1928
1929
/** Definition of a field domain for field content validated by a glob.
1930
 *
1931
 * Globs are matching expression like "*[a-z][0-1]?"
1932
 */
1933
class CPL_DLL OGRGlobFieldDomain final : public OGRFieldDomain
1934
{
1935
  private:
1936
    std::string m_osGlob;
1937
1938
    OGRGlobFieldDomain(const OGRGlobFieldDomain &) = delete;
1939
    OGRGlobFieldDomain &operator=(const OGRGlobFieldDomain &) = delete;
1940
1941
  public:
1942
    /** Constructor.
1943
     *
1944
     * This is the same as the C function OGR_GlobFldDomain_Create().
1945
     *
1946
     * @param osName          Domain name.
1947
     * @param osDescription   Domain description.
1948
     * @param eFieldType      Field type.
1949
     * @param eFieldSubType   Field subtype.
1950
     * @param osBlob          Blob expression
1951
     */
1952
    OGRGlobFieldDomain(const std::string &osName,
1953
                       const std::string &osDescription,
1954
                       OGRFieldType eFieldType, OGRFieldSubType eFieldSubType,
1955
                       const std::string &osBlob);
1956
1957
    OGRGlobFieldDomain *Clone() const override;
1958
1959
    /** Get the glob expression.
1960
     *
1961
     * This is the same as the C function OGR_GlobFldDomain_GetGlob().
1962
     */
1963
    const std::string &GetGlob() const
1964
0
    {
1965
0
        return m_osGlob;
1966
0
    }
1967
};
1968
1969
/************************************************************************/
1970
/*                           OGRFeatureQuery                            */
1971
/************************************************************************/
1972
1973
//! @cond Doxygen_Suppress
1974
class OGRLayer;
1975
class swq_expr_node;
1976
class swq_custom_func_registrar;
1977
struct swq_evaluation_context;
1978
1979
class CPL_DLL OGRFeatureQuery
1980
{
1981
  private:
1982
    const OGRFeatureDefn *poTargetDefn;
1983
    void *pSWQExpr;
1984
    swq_evaluation_context *m_psContext = nullptr;
1985
1986
    char **FieldCollector(void *, char **);
1987
1988
    static GIntBig *EvaluateAgainstIndices(const swq_expr_node *, OGRLayer *,
1989
                                           GIntBig &nFIDCount);
1990
1991
    static int CanUseIndex(const swq_expr_node *, OGRLayer *);
1992
1993
    OGRErr Compile(const OGRLayer *, const OGRFeatureDefn *, const char *,
1994
                   int bCheck,
1995
                   swq_custom_func_registrar *poCustomFuncRegistrar);
1996
1997
    CPL_DISALLOW_COPY_ASSIGN(OGRFeatureQuery)
1998
1999
  public:
2000
    OGRFeatureQuery();
2001
    ~OGRFeatureQuery();
2002
2003
    OGRErr Compile(const OGRLayer *, const char *, int bCheck = TRUE,
2004
                   swq_custom_func_registrar *poCustomFuncRegistrar = nullptr);
2005
    OGRErr Compile(const OGRFeatureDefn *, const char *, int bCheck = TRUE,
2006
                   swq_custom_func_registrar *poCustomFuncRegistrar = nullptr);
2007
    int Evaluate(OGRFeature *);
2008
2009
    GIntBig *EvaluateAgainstIndices(OGRLayer *, OGRErr *);
2010
2011
    int CanUseIndex(OGRLayer *);
2012
2013
    char **GetUsedFields();
2014
2015
    void *GetSWQExpr()
2016
0
    {
2017
0
        return pSWQExpr;
2018
0
    }
2019
};
2020
2021
//! @endcond
2022
2023
#endif /* ndef OGR_FEATURE_H_INCLUDED */