Line data Source code
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 2987 : 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 2760 : MEMGroup(const std::string &osParentName, const char *pszName)
71 2760 : : GDALGroup(osParentName, pszName ? pszName : "")
72 : {
73 2760 : if (!osParentName.empty() && !pszName)
74 2586 : m_osFullName = osParentName;
75 2760 : }
76 :
77 : public:
78 : static std::shared_ptr<MEMGroup> Create(const std::string &osParentName,
79 : const char *pszName);
80 :
81 25 : void SetFullName(const std::string &osFullName)
82 : {
83 25 : m_osFullName = osFullName;
84 25 : }
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 7120 : GetDimensions() const override
206 : {
207 7120 : return m_aoDims;
208 : }
209 :
210 4402 : const GDALExtendedDataType &GetDataType() const override
211 : {
212 4402 : return m_oType;
213 : }
214 :
215 : bool
216 : Init(GByte *pData = nullptr,
217 : const std::vector<GPtrDiff_t> &anStrides = std::vector<GPtrDiff_t>());
218 :
219 341 : void SetWritable(bool bWritable)
220 : {
221 341 : m_bWritable = bWritable;
222 341 : }
223 :
224 543 : bool IsModified() const
225 : {
226 543 : return m_bModified;
227 : }
228 :
229 465 : void SetModified(bool bModified)
230 : {
231 465 : m_bModified = bModified;
232 465 : }
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 227 : Create(const std::string &osParentName, const std::string &osName,
282 : const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
283 : const GDALExtendedDataType &oType)
284 : {
285 : auto array(std::shared_ptr<MEMMDArray>(
286 227 : new MEMMDArray(osParentName, osName, aoDimensions, oType)));
287 227 : array->SetSelf(array);
288 227 : return array;
289 : }
290 :
291 : ~MEMMDArray();
292 :
293 0 : void Invalidate()
294 : {
295 0 : m_bValid = false;
296 0 : }
297 :
298 35 : bool IsWritable() const override
299 : {
300 35 : return m_bWritable;
301 : }
302 :
303 281 : const std::string &GetFilename() const override
304 : {
305 281 : return m_osFilename;
306 : }
307 :
308 206 : void RegisterGroup(const std::weak_ptr<GDALGroup> &group)
309 : {
310 206 : m_poGroupWeak = group;
311 206 : }
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 59 : const std::string &GetUnit() const override
329 : {
330 59 : return m_osUnit;
331 : }
332 :
333 14 : bool SetUnit(const std::string &osUnit) override
334 : {
335 14 : m_osUnit = osUnit;
336 14 : return true;
337 : }
338 :
339 14 : bool SetSpatialRef(const OGRSpatialReference *poSRS) override
340 : {
341 14 : m_poSRS.reset(poSRS ? poSRS->Clone() : nullptr);
342 14 : return true;
343 : }
344 :
345 52 : std::shared_ptr<OGRSpatialReference> GetSpatialRef() const override
346 : {
347 52 : return m_poSRS;
348 : }
349 :
350 : const void *GetRawNoDataValue() const override;
351 :
352 : bool SetRawNoDataValue(const void *) override;
353 :
354 57 : double GetOffset(bool *pbHasOffset,
355 : GDALDataType *peStorageType) const override
356 : {
357 57 : if (pbHasOffset)
358 42 : *pbHasOffset = m_bHasOffset;
359 57 : if (peStorageType)
360 14 : *peStorageType = m_eOffsetStorageType;
361 57 : return m_dfOffset;
362 : }
363 :
364 60 : double GetScale(bool *pbHasScale,
365 : GDALDataType *peStorageType) const override
366 : {
367 60 : if (pbHasScale)
368 45 : *pbHasScale = m_bHasScale;
369 60 : if (peStorageType)
370 14 : *peStorageType = m_eScaleStorageType;
371 60 : return m_dfScale;
372 : }
373 :
374 20 : bool SetOffset(double dfOffset, GDALDataType eStorageType) override
375 : {
376 20 : m_bHasOffset = true;
377 20 : m_dfOffset = dfOffset;
378 20 : m_eOffsetStorageType = eStorageType;
379 20 : return true;
380 : }
381 :
382 20 : bool SetScale(double dfScale, GDALDataType eStorageType) override
383 : {
384 20 : m_bHasScale = true;
385 20 : m_dfScale = dfScale;
386 20 : m_eScaleStorageType = eStorageType;
387 20 : return true;
388 : }
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 0 : std::shared_ptr<GDALGroup> GetRootGroup() const override
399 : {
400 0 : return m_poRootGroupWeak.lock();
401 : }
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 12 : const std::set<MEMMDArray *> &GetUsingArrays() const
466 : {
467 12 : return m_oSetArrays;
468 : }
469 :
470 : bool Rename(const std::string &osNewName) override;
471 : };
472 :
473 : #endif // MEMMULTIDIM_H
|