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