Coverage Report

Created: 2026-04-01 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/frmts/mem/memdataset.h
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  Memory Array Translator
4
 * Purpose:  Declaration of MEMDataset, and MEMRasterBand.
5
 * Author:   Frank Warmerdam, warmerdam@pobox.com
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2000, Frank Warmerdam
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#ifndef MEMDATASET_H_INCLUDED
14
#define MEMDATASET_H_INCLUDED
15
16
#include "gdal_pam.h"
17
#include "gdal_priv.h"
18
#include "gdal_rat.h"
19
#include "ogrsf_frmts.h"
20
21
#include <map>
22
#include <memory>
23
24
CPL_C_START
25
26
void CPL_DLL GDALRegister_MEM();
27
28
/* Caution: if changing this prototype, also change in
29
   swig/include/gdal_python.i where it is redefined */
30
GDALRasterBandH CPL_DLL MEMCreateRasterBand(GDALDataset *, int, GByte *,
31
                                            GDALDataType, int, int, int);
32
GDALRasterBandH CPL_DLL MEMCreateRasterBandEx(GDALDataset *, int, GByte *,
33
                                              GDALDataType, GSpacing, GSpacing,
34
                                              int);
35
CPL_C_END
36
37
/************************************************************************/
38
/*                              MEMDataset                              */
39
/************************************************************************/
40
41
class MEMRasterBand;
42
class OGRMemLayer;
43
44
class CPL_DLL MEMDataset CPL_NON_FINAL : public GDALDataset
45
{
46
    CPL_DISALLOW_COPY_ASSIGN(MEMDataset)
47
48
    friend class MEMRasterBand;
49
50
    int bGeoTransformSet;
51
    GDALGeoTransform m_gt{};
52
53
    OGRSpatialReference m_oSRS{};
54
55
    std::vector<gdal::GCP> m_aoGCPs{};
56
    OGRSpatialReference m_oGCPSRS{};
57
58
    using GDALDatasetRefCountedPtr =
59
        std::unique_ptr<GDALDataset, GDALDatasetUniquePtrReleaser>;
60
61
    std::vector<GDALDatasetRefCountedPtr> m_apoOverviewDS{};
62
63
    struct Private;
64
    std::unique_ptr<Private> m_poPrivate;
65
66
    std::vector<std::unique_ptr<OGRMemLayer>> m_apoLayers{};
67
68
#if 0
69
  protected:
70
    virtual int                 EnterReadWrite(GDALRWFlag eRWFlag);
71
    virtual void                LeaveReadWrite();
72
#endif
73
74
    friend void GDALRegister_MEM();
75
76
    // cppcheck-suppress unusedPrivateFunction
77
    static GDALDataset *CreateBase(const char *pszFilename, int nXSize,
78
                                   int nYSize, int nBands, GDALDataType eType,
79
                                   CSLConstList papszParamList);
80
81
  protected:
82
    bool CanBeCloned(int nScopeFlags, bool bCanShareState) const override;
83
84
    std::unique_ptr<GDALDataset> Clone(int nScopeFlags,
85
                                       bool bCanShareState) const override;
86
87
  public:
88
    MEMDataset();
89
    ~MEMDataset() override;
90
91
    CPLErr Close(GDALProgressFunc = nullptr, void * = nullptr) override;
92
93
    const OGRSpatialReference *GetSpatialRef() const override;
94
    const OGRSpatialReference *GetSpatialRefRasterOnly() const override;
95
    CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override;
96
97
    CPLErr GetGeoTransform(GDALGeoTransform &gt) const override;
98
    CPLErr SetGeoTransform(const GDALGeoTransform &gt) override;
99
100
    void *GetInternalHandle(const char *) override;
101
102
    int GetGCPCount() override;
103
    const OGRSpatialReference *GetGCPSpatialRef() const override;
104
    const GDAL_GCP *GetGCPs() override;
105
    CPLErr SetGCPs(int nGCPCount, const GDAL_GCP *pasGCPList,
106
                   const OGRSpatialReference *poSRS) override;
107
    virtual CPLErr AddBand(GDALDataType eType,
108
                           CSLConstList papszOptions = nullptr) override;
109
    CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
110
                     int nYSize, void *pData, int nBufXSize, int nBufYSize,
111
                     GDALDataType eBufType, int nBandCount,
112
                     BANDMAP_TYPE panBandMap, GSpacing nPixelSpaceBuf,
113
                     GSpacing nLineSpaceBuf, GSpacing nBandSpaceBuf,
114
                     GDALRasterIOExtraArg *psExtraArg) override;
115
    CPLErr IBuildOverviews(const char *pszResampling, int nOverviews,
116
                           const int *panOverviewList, int nListBands,
117
                           const int *panBandList, GDALProgressFunc pfnProgress,
118
                           void *pProgressData,
119
                           CSLConstList papszOptions) override;
120
121
    CPLErr CreateMaskBand(int nFlagsIn) override;
122
123
    std::shared_ptr<GDALGroup> GetRootGroup() const override;
124
125
    void AddMEMBand(GDALRasterBandH hMEMBand);
126
127
    static GDALDataset *Open(GDALOpenInfo *);
128
    static MEMDataset *Create(const char *pszFilename, int nXSize, int nYSize,
129
                              int nBands, GDALDataType eType,
130
                              CSLConstList papszParamList);
131
    static GDALDataset *
132
    CreateMultiDimensional(const char *pszFilename,
133
                           CSLConstList papszRootGroupOptions,
134
                           CSLConstList papszOptions);
135
136
    // Vector capabilities
137
138
    int GetLayerCount() const override
139
0
    {
140
0
        return static_cast<int>(m_apoLayers.size());
141
0
    }
142
143
    const OGRLayer *GetLayer(int) const override;
144
145
    using GDALDataset::CreateLayer;
146
147
    OGRMemLayer *CreateLayer(const OGRFeatureDefn &oDefn,
148
                             CSLConstList papszOptions);
149
150
    OGRLayer *ICreateLayer(const char *pszName,
151
                           const OGRGeomFieldDefn *poGeomFieldDefn,
152
                           CSLConstList papszOptions) override;
153
    OGRErr DeleteLayer(int iLayer) override;
154
155
    int TestCapability(const char *) const override;
156
157
    OGRLayer *ExecuteSQL(const char *pszStatement, OGRGeometry *poSpatialFilter,
158
                         const char *pszDialect) override;
159
160
    bool AddFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain,
161
                        std::string &failureReason) override;
162
163
    bool DeleteFieldDomain(const std::string &name,
164
                           std::string &failureReason) override;
165
166
    bool UpdateFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain,
167
                           std::string &failureReason) override;
168
169
    std::vector<std::string>
170
    GetRelationshipNames(CSLConstList papszOptions = nullptr) const override;
171
172
    const GDALRelationship *
173
    GetRelationship(const std::string &name) const override;
174
175
    bool AddRelationship(std::unique_ptr<GDALRelationship> &&relationship,
176
                         std::string &failureReason) override;
177
178
    bool DeleteRelationship(const std::string &name,
179
                            std::string &failureReason) override;
180
181
    bool UpdateRelationship(std::unique_ptr<GDALRelationship> &&relationship,
182
                            std::string &failureReason) override;
183
};
184
185
/************************************************************************/
186
/*                            MEMRasterBand                             */
187
/************************************************************************/
188
189
class CPL_DLL MEMRasterBand CPL_NON_FINAL : public GDALPamRasterBand
190
{
191
  private:
192
    CPL_DISALLOW_COPY_ASSIGN(MEMRasterBand)
193
194
  protected:
195
    friend class MEMDataset;
196
197
    GByte *pabyData;
198
    GSpacing nPixelOffset;
199
    GSpacing nLineOffset;
200
    int bOwnData;
201
202
    bool m_bIsMask = false;
203
204
    MEMRasterBand(GByte *pabyDataIn, GDALDataType eTypeIn, int nXSizeIn,
205
                  int nYSizeIn, bool bOwnDataIn);
206
207
  public:
208
    MEMRasterBand(GDALDataset *poDS, int nBand, GByte *pabyData,
209
                  GDALDataType eType, GSpacing nPixelOffset,
210
                  GSpacing nLineOffset, int bAssumeOwnership,
211
                  const char *pszPixelType = nullptr);
212
    ~MEMRasterBand() override;
213
214
    CPLErr IReadBlock(int, int, void *) override;
215
    CPLErr IWriteBlock(int, int, void *) override;
216
    CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
217
                     int nYSize, void *pData, int nBufXSize, int nBufYSize,
218
                     GDALDataType eBufType, GSpacing nPixelSpaceBuf,
219
                     GSpacing nLineSpaceBuf,
220
                     GDALRasterIOExtraArg *psExtraArg) override;
221
222
    int GetOverviewCount() override;
223
    GDALRasterBand *GetOverview(int) override;
224
225
    CPLErr CreateMaskBand(int nFlagsIn) override;
226
    bool IsMaskBand() const override;
227
228
    // Allow access to MEM driver's private internal memory buffer.
229
    GByte *GetData() const
230
0
    {
231
0
        return (pabyData);
232
0
    }
233
};
234
235
/************************************************************************/
236
/*                             OGRMemLayer                              */
237
/************************************************************************/
238
239
class IOGRMemLayerFeatureIterator;
240
241
class CPL_DLL OGRMemLayer CPL_NON_FINAL : public OGRLayer
242
{
243
    CPL_DISALLOW_COPY_ASSIGN(OGRMemLayer)
244
245
    typedef std::map<GIntBig, std::unique_ptr<OGRFeature>> FeatureMap;
246
    typedef FeatureMap::iterator FeatureIterator;
247
248
    OGRFeatureDefn *m_poFeatureDefn = nullptr;
249
250
    GIntBig m_nFeatureCount = 0;
251
252
    GIntBig m_iNextReadFID = 0;
253
    GIntBig m_nMaxFeatureCount = 0;  // Max size of papoFeatures.
254
    OGRFeature **m_papoFeatures = nullptr;
255
    bool m_bHasHoles = false;
256
257
    FeatureMap m_oMapFeatures{};
258
    FeatureIterator m_oMapFeaturesIter{};
259
260
    GIntBig m_iNextCreateFID = 0;
261
262
    bool m_bUpdatable = true;
263
    bool m_bAdvertizeUTF8 = false;
264
265
    bool m_bUpdated = false;
266
267
    std::string m_osFIDColumn{};
268
269
    GDALDataset *m_poDS{};
270
271
    // Only use it in the lifetime of a function where the list of features
272
    // doesn't change.
273
    IOGRMemLayerFeatureIterator *GetIterator();
274
    void PrepareCreateFeature(OGRFeature *poFeature);
275
    OGRErr SetFeatureInternal(std::unique_ptr<OGRFeature> poFeature,
276
                              GIntBig *pnFID = nullptr);
277
278
  protected:
279
    OGRFeature *GetFeatureRef(GIntBig nFeatureId);
280
281
  public:
282
    // Clone poSRS if not nullptr
283
    OGRMemLayer(const char *pszName, const OGRSpatialReference *poSRS,
284
                OGRwkbGeometryType eGeomType);
285
    explicit OGRMemLayer(const OGRFeatureDefn &oFeatureDefn);
286
    ~OGRMemLayer() override;
287
288
    void ResetReading() override;
289
    OGRFeature *GetNextFeature() override;
290
    OGRErr SetNextByIndex(GIntBig nIndex) override;
291
292
    OGRFeature *GetFeature(GIntBig nFeatureId) override;
293
294
    OGRErr ISetFeatureUniqPtr(std::unique_ptr<OGRFeature> poFeature) override;
295
    OGRErr ISetFeature(OGRFeature *poFeature) override;
296
297
    OGRErr ICreateFeatureUniqPtr(std::unique_ptr<OGRFeature> poFeature,
298
                                 GIntBig *pnFID = nullptr) override;
299
    OGRErr ICreateFeature(OGRFeature *poFeature) override;
300
301
    OGRErr IUpsertFeature(OGRFeature *poFeature) override;
302
    OGRErr IUpdateFeature(OGRFeature *poFeature, int nUpdatedFieldsCount,
303
                          const int *panUpdatedFieldsIdx,
304
                          int nUpdatedGeomFieldsCount,
305
                          const int *panUpdatedGeomFieldsIdx,
306
                          bool bUpdateStyleString) override;
307
    OGRErr DeleteFeature(GIntBig nFID) override;
308
309
    using OGRLayer::GetLayerDefn;
310
311
    const OGRFeatureDefn *GetLayerDefn() const override
312
0
    {
313
0
        return m_poFeatureDefn;
314
0
    }
315
316
    GIntBig GetFeatureCount(int = true) override;
317
318
    virtual OGRErr CreateField(const OGRFieldDefn *poField,
319
                               int bApproxOK = TRUE) override;
320
    OGRErr DeleteField(int iField) override;
321
    OGRErr ReorderFields(int *panMap) override;
322
    virtual OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
323
                                  int nFlags) override;
324
    virtual OGRErr
325
    AlterGeomFieldDefn(int iGeomField,
326
                       const OGRGeomFieldDefn *poNewGeomFieldDefn,
327
                       int nFlagsIn) override;
328
    virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poGeomField,
329
                                   int bApproxOK = TRUE) override;
330
331
    int TestCapability(const char *) const override;
332
333
    const char *GetFIDColumn() const override
334
0
    {
335
0
        return m_osFIDColumn.c_str();
336
0
    }
337
338
    bool IsUpdatable() const
339
0
    {
340
0
        return m_bUpdatable;
341
0
    }
342
343
    void SetUpdatable(bool bUpdatableIn)
344
0
    {
345
0
        m_bUpdatable = bUpdatableIn;
346
0
    }
347
348
    void SetAdvertizeUTF8(bool bAdvertizeUTF8In)
349
0
    {
350
0
        m_bAdvertizeUTF8 = bAdvertizeUTF8In;
351
0
    }
352
353
    void SetFIDColumn(const char *pszFIDColumn)
354
0
    {
355
0
        m_osFIDColumn = pszFIDColumn;
356
0
    }
357
358
    bool HasBeenUpdated() const
359
0
    {
360
0
        return m_bUpdated;
361
0
    }
362
363
    void SetUpdated(bool bUpdated)
364
0
    {
365
0
        m_bUpdated = bUpdated;
366
0
    }
367
368
    GIntBig GetNextReadFID()
369
0
    {
370
0
        return m_iNextReadFID;
371
0
    }
372
373
    void SetDataset(GDALDataset *poDS)
374
0
    {
375
0
        m_poDS = poDS;
376
0
    }
377
378
    GDALDataset *GetDataset() override
379
0
    {
380
0
        return m_poDS;
381
0
    }
382
};
383
384
#endif /* ndef MEMDATASET_H_INCLUDED */