Coverage Report

Created: 2025-06-13 06:29

/src/gdal/frmts/mem/memmultidim.h
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  GDAL
4
 * Purpose:  MEM driver multidimensional classes
5
 * Author:   Even Rouault <even dot rouault at spatialys.com>
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2021, Even Rouault <even dot rouault at spatialys.com>
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#ifndef MEMMULTIDIM_H
14
#define MEMMULTIDIM_H
15
16
#include "gdal_priv.h"
17
18
#include <set>
19
20
// If modifying the below declaration, modify it in gdal_array.i too
21
std::shared_ptr<GDALMDArray> CPL_DLL MEMGroupCreateMDArray(
22
    GDALGroup *poGroup, const std::string &osName,
23
    const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
24
    const GDALExtendedDataType &oDataType, void *pData,
25
    CSLConstList papszOptions);
26
27
/************************************************************************/
28
/*                        MEMAttributeHolder                            */
29
/************************************************************************/
30
31
class CPL_DLL MEMAttributeHolder CPL_NON_FINAL
32
{
33
  protected:
34
    std::map<CPLString, std::shared_ptr<GDALAttribute>> m_oMapAttributes{};
35
36
  public:
37
    virtual ~MEMAttributeHolder();
38
39
    bool RenameAttribute(const std::string &osOldName,
40
                         const std::string &osNewName);
41
};
42
43
/************************************************************************/
44
/*                               MEMGroup                               */
45
/************************************************************************/
46
47
class CPL_DLL MEMGroup CPL_NON_FINAL : public GDALGroup,
48
                                       public MEMAttributeHolder
49
{
50
    friend class MEMMDArray;
51
52
    std::map<CPLString, std::shared_ptr<GDALGroup>> m_oMapGroups{};
53
    std::map<CPLString, std::shared_ptr<GDALMDArray>> m_oMapMDArrays{};
54
    std::map<CPLString, std::shared_ptr<GDALDimension>> m_oMapDimensions{};
55
    std::weak_ptr<MEMGroup> m_pParent{};
56
    std::weak_ptr<GDALGroup> m_poRootGroupWeak{};
57
58
  protected:
59
    friend class MEMDimension;
60
    bool RenameDimension(const std::string &osOldName,
61
                         const std::string &osNewName);
62
63
    bool RenameArray(const std::string &osOldName,
64
                     const std::string &osNewName);
65
66
    void NotifyChildrenOfRenaming() override;
67
68
    void NotifyChildrenOfDeletion() override;
69
70
    MEMGroup(const std::string &osParentName, const char *pszName)
71
0
        : GDALGroup(osParentName, pszName ? pszName : "")
72
0
    {
73
0
        if (!osParentName.empty() && !pszName)
74
0
            m_osFullName = osParentName;
75
0
    }
76
77
  public:
78
    static std::shared_ptr<MEMGroup> Create(const std::string &osParentName,
79
                                            const char *pszName);
80
81
    void SetFullName(const std::string &osFullName)
82
0
    {
83
0
        m_osFullName = osFullName;
84
0
    }
85
86
    std::vector<std::string>
87
    GetMDArrayNames(CSLConstList papszOptions) const override;
88
    std::shared_ptr<GDALMDArray>
89
    OpenMDArray(const std::string &osName,
90
                CSLConstList papszOptions) const override;
91
92
    std::vector<std::string>
93
    GetGroupNames(CSLConstList papszOptions) const override;
94
    std::shared_ptr<GDALGroup>
95
    OpenGroup(const std::string &osName,
96
              CSLConstList papszOptions) const override;
97
98
    std::shared_ptr<GDALGroup> CreateGroup(const std::string &osName,
99
                                           CSLConstList papszOptions) override;
100
101
    bool DeleteGroup(const std::string &osName,
102
                     CSLConstList papszOptions) override;
103
104
    std::shared_ptr<GDALDimension>
105
    CreateDimension(const std::string &, const std::string &,
106
                    const std::string &, GUInt64,
107
                    CSLConstList papszOptions) override;
108
109
    std::shared_ptr<GDALMDArray> CreateMDArray(
110
        const std::string &osName,
111
        const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
112
        const GDALExtendedDataType &oDataType,
113
        CSLConstList papszOptions) override;
114
115
    std::shared_ptr<GDALMDArray> CreateMDArray(
116
        const std::string &osName,
117
        const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
118
        const GDALExtendedDataType &oDataType, void *pData,
119
        CSLConstList papszOptions);
120
121
    bool DeleteMDArray(const std::string &osName,
122
                       CSLConstList papszOptions) override;
123
124
    std::shared_ptr<GDALAttribute>
125
    GetAttribute(const std::string &osName) const override;
126
127
    std::vector<std::shared_ptr<GDALAttribute>>
128
    GetAttributes(CSLConstList papszOptions) const override;
129
130
    std::vector<std::shared_ptr<GDALDimension>>
131
    GetDimensions(CSLConstList papszOptions) const override;
132
133
    std::shared_ptr<GDALAttribute>
134
    CreateAttribute(const std::string &osName,
135
                    const std::vector<GUInt64> &anDimensions,
136
                    const GDALExtendedDataType &oDataType,
137
                    CSLConstList papszOptions) override;
138
139
    bool DeleteAttribute(const std::string &osName,
140
                         CSLConstList papszOptions) override;
141
142
    bool Rename(const std::string &osNewName) override;
143
};
144
145
/************************************************************************/
146
/*                            MEMAbstractMDArray                        */
147
/************************************************************************/
148
149
class CPL_DLL MEMAbstractMDArray : virtual public GDALAbstractMDArray
150
{
151
    std::vector<std::shared_ptr<GDALDimension>> m_aoDims;
152
153
    struct StackReadWrite
154
    {
155
        size_t nIters = 0;
156
        const GByte *src_ptr = nullptr;
157
        GByte *dst_ptr = nullptr;
158
        GPtrDiff_t src_inc_offset = 0;
159
        GPtrDiff_t dst_inc_offset = 0;
160
    };
161
162
    void ReadWrite(bool bIsWrite, const size_t *count,
163
                   std::vector<StackReadWrite> &stack,
164
                   const GDALExtendedDataType &srcType,
165
                   const GDALExtendedDataType &dstType) const;
166
167
    MEMAbstractMDArray(const MEMAbstractMDArray &) = delete;
168
    MEMAbstractMDArray &operator=(const MEMAbstractMDArray &) = delete;
169
170
  protected:
171
    bool m_bOwnArray = false;
172
    bool m_bWritable = true;
173
    bool m_bModified = false;
174
    GDALExtendedDataType m_oType;
175
    size_t m_nTotalSize = 0;
176
    GByte *m_pabyArray{};
177
    std::vector<GPtrDiff_t> m_anStrides{};
178
179
    bool
180
    IRead(const GUInt64 *arrayStartIdx,    // array of size GetDimensionCount()
181
          const size_t *count,             // array of size GetDimensionCount()
182
          const GInt64 *arrayStep,         // step in elements
183
          const GPtrDiff_t *bufferStride,  // stride in elements
184
          const GDALExtendedDataType &bufferDataType,
185
          void *pDstBuffer) const override;
186
187
    bool
188
    IWrite(const GUInt64 *arrayStartIdx,    // array of size GetDimensionCount()
189
           const size_t *count,             // array of size GetDimensionCount()
190
           const GInt64 *arrayStep,         // step in elements
191
           const GPtrDiff_t *bufferStride,  // stride in elements
192
           const GDALExtendedDataType &bufferDataType,
193
           const void *pSrcBuffer) override;
194
195
    void FreeArray();
196
197
  public:
198
    MEMAbstractMDArray(
199
        const std::string &osParentName, const std::string &osName,
200
        const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
201
        const GDALExtendedDataType &oType);
202
    ~MEMAbstractMDArray();
203
204
    const std::vector<std::shared_ptr<GDALDimension>> &
205
    GetDimensions() const override
206
0
    {
207
0
        return m_aoDims;
208
0
    }
209
210
    const GDALExtendedDataType &GetDataType() const override
211
0
    {
212
0
        return m_oType;
213
0
    }
214
215
    bool
216
    Init(GByte *pData = nullptr,
217
         const std::vector<GPtrDiff_t> &anStrides = std::vector<GPtrDiff_t>());
218
219
    void SetWritable(bool bWritable)
220
0
    {
221
0
        m_bWritable = bWritable;
222
0
    }
223
224
    bool IsModified() const
225
0
    {
226
0
        return m_bModified;
227
0
    }
228
229
    void SetModified(bool bModified)
230
0
    {
231
0
        m_bModified = bModified;
232
0
    }
233
};
234
235
/************************************************************************/
236
/*                                MEMMDArray                            */
237
/************************************************************************/
238
239
#ifdef _MSC_VER
240
#pragma warning(push)
241
// warning C4250: 'MEMMDArray': inherits
242
// 'MEMAbstractMDArray::MEMAbstractMDArray::IRead' via dominance
243
#pragma warning(disable : 4250)
244
#endif  //_MSC_VER
245
246
class CPL_DLL MEMMDArray CPL_NON_FINAL : public MEMAbstractMDArray,
247
                                         public GDALMDArray,
248
                                         public MEMAttributeHolder
249
{
250
    std::string m_osUnit{};
251
    std::shared_ptr<OGRSpatialReference> m_poSRS{};
252
    GByte *m_pabyNoData = nullptr;
253
    double m_dfScale = 1.0;
254
    double m_dfOffset = 0.0;
255
    bool m_bHasScale = false;
256
    bool m_bHasOffset = false;
257
    GDALDataType m_eOffsetStorageType = GDT_Unknown;
258
    GDALDataType m_eScaleStorageType = GDT_Unknown;
259
    std::string m_osFilename{};
260
    std::weak_ptr<GDALGroup> m_poGroupWeak{};
261
    std::weak_ptr<GDALGroup> m_poRootGroupWeak{};
262
263
    MEMMDArray(const MEMMDArray &) = delete;
264
    MEMMDArray &operator=(const MEMMDArray &) = delete;
265
266
    bool Resize(const std::vector<GUInt64> &anNewDimSizes,
267
                bool bResizeOtherArrays);
268
269
    void NotifyChildrenOfRenaming() override;
270
271
    void NotifyChildrenOfDeletion() override;
272
273
  protected:
274
    MEMMDArray(const std::string &osParentName, const std::string &osName,
275
               const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
276
               const GDALExtendedDataType &oType);
277
278
  public:
279
    // MEMAbstractMDArray::Init() should be called afterwards
280
    static std::shared_ptr<MEMMDArray>
281
    Create(const std::string &osParentName, const std::string &osName,
282
           const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
283
           const GDALExtendedDataType &oType)
284
0
    {
285
0
        auto array(std::shared_ptr<MEMMDArray>(
286
0
            new MEMMDArray(osParentName, osName, aoDimensions, oType)));
287
0
        array->SetSelf(array);
288
0
        return array;
289
0
    }
290
291
    ~MEMMDArray();
292
293
    void Invalidate()
294
0
    {
295
0
        m_bValid = false;
296
0
    }
297
298
    bool IsWritable() const override
299
0
    {
300
0
        return m_bWritable;
301
0
    }
302
303
    const std::string &GetFilename() const override
304
0
    {
305
0
        return m_osFilename;
306
0
    }
307
308
    void RegisterGroup(const std::weak_ptr<GDALGroup> &group)
309
0
    {
310
0
        m_poGroupWeak = group;
311
0
    }
312
313
    std::shared_ptr<GDALAttribute>
314
    GetAttribute(const std::string &osName) const override;
315
316
    std::vector<std::shared_ptr<GDALAttribute>>
317
    GetAttributes(CSLConstList papszOptions) const override;
318
319
    std::shared_ptr<GDALAttribute>
320
    CreateAttribute(const std::string &osName,
321
                    const std::vector<GUInt64> &anDimensions,
322
                    const GDALExtendedDataType &oDataType,
323
                    CSLConstList papszOptions) override;
324
325
    bool DeleteAttribute(const std::string &osName,
326
                         CSLConstList papszOptions) override;
327
328
    const std::string &GetUnit() const override
329
0
    {
330
0
        return m_osUnit;
331
0
    }
332
333
    bool SetUnit(const std::string &osUnit) override
334
0
    {
335
0
        m_osUnit = osUnit;
336
0
        return true;
337
0
    }
338
339
    bool SetSpatialRef(const OGRSpatialReference *poSRS) override
340
0
    {
341
0
        m_poSRS.reset(poSRS ? poSRS->Clone() : nullptr);
342
0
        return true;
343
0
    }
344
345
    std::shared_ptr<OGRSpatialReference> GetSpatialRef() const override
346
0
    {
347
0
        return m_poSRS;
348
0
    }
349
350
    const void *GetRawNoDataValue() const override;
351
352
    bool SetRawNoDataValue(const void *) override;
353
354
    double GetOffset(bool *pbHasOffset,
355
                     GDALDataType *peStorageType) const override
356
0
    {
357
0
        if (pbHasOffset)
358
0
            *pbHasOffset = m_bHasOffset;
359
0
        if (peStorageType)
360
0
            *peStorageType = m_eOffsetStorageType;
361
0
        return m_dfOffset;
362
0
    }
363
364
    double GetScale(bool *pbHasScale,
365
                    GDALDataType *peStorageType) const override
366
0
    {
367
0
        if (pbHasScale)
368
0
            *pbHasScale = m_bHasScale;
369
0
        if (peStorageType)
370
0
            *peStorageType = m_eScaleStorageType;
371
0
        return m_dfScale;
372
0
    }
373
374
    bool SetOffset(double dfOffset, GDALDataType eStorageType) override
375
0
    {
376
0
        m_bHasOffset = true;
377
0
        m_dfOffset = dfOffset;
378
0
        m_eOffsetStorageType = eStorageType;
379
0
        return true;
380
0
    }
381
382
    bool SetScale(double dfScale, GDALDataType eStorageType) override
383
0
    {
384
0
        m_bHasScale = true;
385
0
        m_dfScale = dfScale;
386
0
        m_eScaleStorageType = eStorageType;
387
0
        return true;
388
0
    }
389
390
    std::vector<std::shared_ptr<GDALMDArray>>
391
    GetCoordinateVariables() const override;
392
393
    bool Resize(const std::vector<GUInt64> &anNewDimSizes,
394
                CSLConstList) override;
395
396
    bool Rename(const std::string &osNewName) override;
397
398
    std::shared_ptr<GDALGroup> GetRootGroup() const override
399
0
    {
400
0
        return m_poRootGroupWeak.lock();
401
0
    }
402
};
403
404
/************************************************************************/
405
/*                               MEMAttribute                           */
406
/************************************************************************/
407
408
class CPL_DLL MEMAttribute CPL_NON_FINAL : public MEMAbstractMDArray,
409
                                           public GDALAttribute
410
{
411
    std::weak_ptr<MEMAttributeHolder> m_poParent{};
412
413
  protected:
414
    MEMAttribute(const std::string &osParentName, const std::string &osName,
415
                 const std::vector<GUInt64> &anDimensions,
416
                 const GDALExtendedDataType &oType);
417
418
  public:
419
    // May return nullptr as it calls MEMAbstractMDArray::Init() which can
420
    // fail
421
    static std::shared_ptr<MEMAttribute>
422
    Create(const std::string &osParentName, const std::string &osName,
423
           const std::vector<GUInt64> &anDimensions,
424
           const GDALExtendedDataType &oType);
425
426
    static std::shared_ptr<MEMAttribute>
427
    Create(const std::shared_ptr<MEMGroup> &poParentGroup,
428
           const std::string &osName, const std::vector<GUInt64> &anDimensions,
429
           const GDALExtendedDataType &oType);
430
431
    static std::shared_ptr<MEMAttribute>
432
    Create(const std::shared_ptr<MEMMDArray> &poParentArray,
433
           const std::string &osName, const std::vector<GUInt64> &anDimensions,
434
           const GDALExtendedDataType &oType);
435
436
    bool Rename(const std::string &osNewName) override;
437
};
438
439
#ifdef _MSC_VER
440
#pragma warning(pop)
441
#endif  //_MSC_VER
442
443
/************************************************************************/
444
/*                               MEMDimension                           */
445
/************************************************************************/
446
447
class MEMDimension CPL_NON_FINAL : public GDALDimensionWeakIndexingVar
448
{
449
    std::set<MEMMDArray *> m_oSetArrays{};
450
    std::weak_ptr<MEMGroup> m_poParentGroup{};
451
452
  public:
453
    MEMDimension(const std::string &osParentName, const std::string &osName,
454
                 const std::string &osType, const std::string &osDirection,
455
                 GUInt64 nSize);
456
457
    static std::shared_ptr<MEMDimension>
458
    Create(const std::shared_ptr<MEMGroup> &poParentGroupy,
459
           const std::string &osName, const std::string &osType,
460
           const std::string &osDirection, GUInt64 nSize);
461
462
    void RegisterUsingArray(MEMMDArray *poArray);
463
    void UnRegisterUsingArray(MEMMDArray *poArray);
464
465
    const std::set<MEMMDArray *> &GetUsingArrays() const
466
0
    {
467
0
        return m_oSetArrays;
468
0
    }
469
470
    bool Rename(const std::string &osNewName) override;
471
};
472
473
#endif  //  MEMMULTIDIM_H