Coverage Report

Created: 2025-11-16 06:25

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