1 /******************************************************************************
2  * $Id: MultiDimensional.i 98ff02f173f67a9c25b1ab82d80b2293aad9ffa2 2021-05-06 19:07:02 +0200 Even Rouault $
3  *
4  * Name:     MultiDimensional.i
5  * Purpose:  GDAL Core SWIG Interface declarations.
6  * Author:   Even Rouault <even.rouault at spatialys.com>
7  *
8  ******************************************************************************
9  * Copyright (c) 2019, Even Rouault <even.rouault at spatialys.com>
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included
19  * in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  *****************************************************************************/
29 
30 %rename (Group) GDALGroupHS;
31 
32 %apply Pointer NONNULL {const char* name};
33 
34 //************************************************************************
35 //
36 // GDALGroup
37 //
38 //************************************************************************
39 
40 class GDALGroupHS {
41 private:
42   GDALGroupHS();
43 public:
44 %extend {
45 
~GDALGroupHS()46   ~GDALGroupHS() {
47     GDALGroupRelease(self);
48   }
49 
GetName()50   const char* GetName() {
51     return GDALGroupGetName(self);
52   }
53 
GetFullName()54   const char* GetFullName() {
55     return GDALGroupGetFullName(self);
56   }
57 
58 %apply (char **CSL) {char **};
59   char **GetMDArrayNames(char** options = 0) {
60     return GDALGroupGetMDArrayNames( self, options );
61   }
62 %clear char **;
63 
64 %newobject OpenMDArray;
65   GDALMDArrayHS* OpenMDArray( const char* name, char** options = 0) {
66     return GDALGroupOpenMDArray(self, name, options);
67   }
68 
69 %newobject OpenMDArrayFromFullname;
70   GDALMDArrayHS* OpenMDArrayFromFullname( const char* name, char** options = 0) {
71     return GDALGroupOpenMDArrayFromFullname(self, name, options);
72   }
73 
74 %newobject ResolveMDArray;
75   GDALMDArrayHS* ResolveMDArray( const char* name, const char* starting_point, char** options = 0) {
76     return GDALGroupResolveMDArray(self, name, starting_point, options);
77   }
78 
79 %apply (char **CSL) {char **};
80   char **GetGroupNames(char** options = 0) {
81     return GDALGroupGetGroupNames( self, options );
82   }
83 %clear char **;
84 
85 %newobject OpenGroup;
86   GDALGroupHS* OpenGroup( const char* name, char** options = 0) {
87     return GDALGroupOpenGroup(self, name, options);
88   }
89 
90 %newobject OpenGroupFromFullname;
91   GDALGroupHS* OpenGroupFromFullname( const char* name, char** options = 0) {
92     return GDALGroupOpenGroupFromFullname(self, name, options);
93   }
94 
95 #if defined(SWIGPYTHON)
96   void GetDimensions( GDALDimensionHS*** pdims, size_t* pnCount, char** options = 0 ) {
97     *pdims = GDALGroupGetDimensions(self, pnCount, options);
98   }
99 #endif
100 
101 %newobject GetAttribute;
GetAttribute(const char * name)102   GDALAttributeHS* GetAttribute( const char* name) {
103     return GDALGroupGetAttribute(self, name);
104   }
105 
106 #if defined(SWIGPYTHON)
107   void GetAttributes( GDALAttributeHS*** pattrs, size_t* pnCount, char** options = 0 ) {
108     *pattrs = GDALGroupGetAttributes(self, pnCount, options);
109   }
110 #endif
111 
112 %apply (char **dict) { char ** };
GetStructuralInfo()113   char ** GetStructuralInfo () {
114     return GDALGroupGetStructuralInfo( self );
115   }
116 %clear char **;
117 
118 %newobject CreateGroup;
119   GDALGroupHS *CreateGroup( const char *name,
120                             char **options = 0 ) {
121     return GDALGroupCreateGroup(self, name, options);
122   }
123 
124 %newobject CreateDimension;
125   GDALDimensionHS *CreateDimension( const char *name,
126                                     const char* type,
127                                     const char* direction,
128                                     unsigned long long size,
129                                     char **options = 0 ) {
130     return GDALGroupCreateDimension(self, name, type, direction, size, options);
131   }
132 
133 #if defined(SWIGPYTHON)
134 %newobject CreateMDArray;
135 %apply (int object_list_count, GDALDimensionHS **poObjects) {(int nDimensions, GDALDimensionHS **dimensions)};
136 %apply Pointer NONNULL {GDALExtendedDataTypeHS* data_type};
137   GDALMDArrayHS *CreateMDArray(const char* name,
138                                int nDimensions,
139                                GDALDimensionHS** dimensions,
140                                GDALExtendedDataTypeHS* data_type,
141                                char **options = 0)
142   {
143     return GDALGroupCreateMDArray(self, name, nDimensions, dimensions,
144                                   data_type, options);
145   }
146 %clear (int nDimensions, GDALDimensionHS **dimensions);
147 #endif
148 
149 %newobject CreateAttribute;
150 %apply (int nList, GUIntBig* pList) {(int nDimensions, GUIntBig *dimensions)};
151   GDALAttributeHS *CreateAttribute( const char *name,
152                                     int nDimensions,
153                                     GUIntBig *dimensions,
154                                     GDALExtendedDataTypeHS* data_type,
155                                     char **options = 0)
156   {
157     return GDALGroupCreateAttribute(self, name, nDimensions,
158                                     (const GUInt64*)dimensions,
159                                     data_type, options);
160   }
161 
162 } /* extend */
163 }; /* GDALGroupH */
164 
165 //************************************************************************
166 //
167 // Statistics
168 //
169 //************************************************************************
170 
171 #ifndef SWIGCSHARP
172 %{
173 typedef struct
174 {
175   double min;
176   double max;
177   double mean;
178   double std_dev;
179   GIntBig valid_count;
180 } Statistics;
181 %}
182 
183 struct Statistics
184 {
185 %immutable;
186   double min;
187   double max;
188   double mean;
189   double std_dev;
190   GIntBig valid_count;
191 %mutable;
192 
193 %extend {
194 
~StatisticsStatistics195   ~Statistics() {
196     CPLFree(self);
197   }
198 } /* extend */
199 } /* Statistics */ ;
200 #endif
201 
202 //************************************************************************
203 //
204 // GDALMDArray
205 //
206 //************************************************************************
207 
208 %{
209 #include <limits>
210 
CheckNumericDataType(GDALExtendedDataTypeHS * dt)211 static bool CheckNumericDataType(GDALExtendedDataTypeHS* dt)
212 {
213     GDALExtendedDataTypeClass klass = GDALExtendedDataTypeGetClass(dt);
214     if( klass == GEDTC_NUMERIC )
215         return true;
216     if( klass == GEDTC_STRING )
217         return false;
218     CPLAssert( klass == GEDTC_COMPOUND );
219     size_t nCount = 0;
220     GDALEDTComponentH* comps = GDALExtendedDataTypeGetComponents(dt, &nCount);
221     bool ret = true;
222     for( size_t i = 0; i < nCount; i++ )
223     {
224         GDALExtendedDataTypeH tmpType = GDALEDTComponentGetType(comps[i]);
225         ret = CheckNumericDataType(tmpType);
226         GDALExtendedDataTypeRelease(tmpType);
227         if( !ret )
228             break;
229     }
230     GDALExtendedDataTypeFreeComponents(comps, nCount);
231     return ret;
232 }
233 
MDArrayReadWriteCheckArguments(GDALMDArrayHS * array,bool bCheckOnlyDims,int nDims1,GUIntBig * array_start_idx,int nDims2,GUIntBig * count,int nDims3,GIntBig * array_step,int nDims4,GIntBig * buffer_stride,GDALExtendedDataTypeHS * buffer_datatype,size_t * pnBufferSize)234 static CPLErr MDArrayReadWriteCheckArguments(GDALMDArrayHS* array,
235                                              bool bCheckOnlyDims,
236                                              int nDims1, GUIntBig* array_start_idx,
237                                              int nDims2, GUIntBig* count,
238                                              int nDims3, GIntBig* array_step,
239                                              int nDims4, GIntBig* buffer_stride,
240                                              GDALExtendedDataTypeHS* buffer_datatype,
241                                              size_t* pnBufferSize)
242 {
243     const int nExpectedDims = (int)GDALMDArrayGetDimensionCount(array);
244     if( nDims1 != nExpectedDims )
245     {
246         CPLError(CE_Failure, CPLE_AppDefined,
247             "Wrong number of values in array_start_idx");
248         return CE_Failure;
249     }
250     if( nDims2 != nExpectedDims )
251     {
252         CPLError(CE_Failure, CPLE_AppDefined,
253             "Wrong number of values in count");
254         return CE_Failure;
255     }
256     if( nDims3 != nExpectedDims )
257     {
258         CPLError(CE_Failure, CPLE_AppDefined,
259             "Wrong number of values in array_step");
260         return CE_Failure;
261     }
262     if( nDims4!= nExpectedDims )
263     {
264         CPLError(CE_Failure, CPLE_AppDefined,
265             "Wrong number of values in buffer_stride");
266         return CE_Failure;
267     }
268     if( bCheckOnlyDims )
269         return CE_None;
270     if( !CheckNumericDataType(buffer_datatype) )
271     {
272         CPLError(CE_Failure, CPLE_NotSupported,
273             "non-numeric buffer data type not supported in SWIG bindings");
274         return CE_Failure;
275     }
276     GIntBig nBufferSize = 0;
277     for( int i = 0; i < nExpectedDims; i++ )
278     {
279         if( count[i] == 0 )
280         {
281             CPLError(CE_Failure, CPLE_AppDefined,
282                      "count[%d] = 0 is invalid", i);
283             return CE_Failure;
284         }
285         if( buffer_stride[i] < 0 )
286         {
287             CPLError(CE_Failure, CPLE_NotSupported,
288                 "Negative value in buffer_stride not supported in SWIG bindings");
289             return CE_Failure;
290         }
291         if( count[i] > 1 && buffer_stride[i] != 0 )
292         {
293             if( (GUIntBig)buffer_stride[i] > std::numeric_limits<GIntBig>::max() / (count[i] - 1) )
294             {
295                 CPLError(CE_Failure, CPLE_AppDefined, "Integer overflow");
296                 return CE_Failure;
297             }
298             GIntBig nDelta = buffer_stride[i] * (count[i] - 1);
299             if( nBufferSize > std::numeric_limits<GIntBig>::max() - nDelta )
300             {
301                 CPLError(CE_Failure, CPLE_AppDefined, "Integer overflow");
302                 return CE_Failure;
303             }
304             nBufferSize += nDelta;
305         }
306     }
307     const size_t nDTSize = GDALExtendedDataTypeGetSize(buffer_datatype);
308     if( nDTSize == 0 )
309     {
310         CPLError(CE_Failure, CPLE_AppDefined, "nDTSize == 0");
311         return CE_Failure;
312     }
313     if( (GUIntBig)nBufferSize > (GUIntBig)std::numeric_limits<GIntBig>::max() / nDTSize )
314     {
315         CPLError(CE_Failure, CPLE_AppDefined, "Integer overflow");
316         return CE_Failure;
317     }
318     nBufferSize *= nDTSize;
319     if( (GUIntBig)nBufferSize > (GUIntBig)std::numeric_limits<GIntBig>::max() - nDTSize )
320     {
321         CPLError(CE_Failure, CPLE_AppDefined, "Integer overflow");
322         return CE_Failure;
323     }
324     nBufferSize += nDTSize;
325 
326 #if SIZEOF_VOIDP == 4
327     if( nBufferSize > INT_MAX )
328     {
329         CPLError(CE_Failure, CPLE_IllegalArg, "Integer overflow");
330         return CE_Failure;
331     }
332 #endif
333     *pnBufferSize = (size_t)nBufferSize;
334     return CE_None;
335 }
336 %}
337 
338 
339 %rename (MDArray) GDALMDArrayHS;
340 
341 class GDALMDArrayHS {
342 private:
343   GDALMDArrayHS();
344 public:
345 %extend {
346 
~GDALMDArrayHS()347   ~GDALMDArrayHS() {
348     GDALMDArrayRelease(self);
349   }
350 
GetName()351   const char* GetName() {
352     return GDALMDArrayGetName(self);
353   }
354 
GetFullName()355   const char* GetFullName() {
356     return GDALMDArrayGetFullName(self);
357   }
358 
GetTotalElementsCount()359   unsigned long long GetTotalElementsCount() {
360     return GDALMDArrayGetTotalElementsCount(self);
361   }
362 
GetDimensionCount()363   size_t GetDimensionCount() {
364     return GDALMDArrayGetDimensionCount(self);
365   }
366 
367 #if defined(SWIGPYTHON)
GetDimensions(GDALDimensionHS *** pdims,size_t * pnCount)368   void GetDimensions( GDALDimensionHS*** pdims, size_t* pnCount ) {
369     *pdims = GDALMDArrayGetDimensions(self, pnCount);
370   }
371 #endif
372 
373 #if defined(SWIGPYTHON)
374 %apply ( GUIntBig** pvals, size_t* pnCount ) { (GUIntBig** psizes, size_t* pnCount ) };
GetBlockSize(GUIntBig ** psizes,size_t * pnCount)375   void GetBlockSize( GUIntBig** psizes, size_t* pnCount ) {
376     *psizes = GDALMDArrayGetBlockSize(self, pnCount);
377   }
378 #endif
379 
380 #if defined(SWIGPYTHON)
381 %apply ( GUIntBig** pvals, size_t* pnCount ) { (GUIntBig** psizes, size_t* pnCount ) };
GetProcessingChunkSize(size_t nMaxChunkMemory,GUIntBig ** psizes,size_t * pnCount)382   void GetProcessingChunkSize( size_t nMaxChunkMemory, GUIntBig** psizes, size_t* pnCount ) {
383      size_t* panTmp = GDALMDArrayGetProcessingChunkSize(self, pnCount, nMaxChunkMemory);
384      *psizes = NULL;
385      if( panTmp )
386      {
387         *psizes = (GUIntBig*) CPLMalloc(sizeof(GUIntBig) * (*pnCount));
388         for( size_t i = 0; i < *pnCount; ++i )
389         {
390             (*psizes)[i] = panTmp[i];
391         }
392         CPLFree(panTmp);
393      }
394   }
395 #endif
396 
397 %newobject GetDataType;
GetDataType()398   GDALExtendedDataTypeHS* GetDataType() {
399     return GDALMDArrayGetDataType(self);
400   }
401 
402 %apply (char **dict) { char ** };
GetStructuralInfo()403   char ** GetStructuralInfo () {
404     return GDALMDArrayGetStructuralInfo( self );
405   }
406 %clear char **;
407 
408 #if defined(SWIGPYTHON)
409 %apply Pointer NONNULL {GDALExtendedDataTypeHS* buffer_datatype};
410 %apply ( void **outPythonObject ) { (void **buf ) };
411 %apply (int nList, GUIntBig* pList) {(int nDims1, GUIntBig *array_start_idx)};
412 %apply (int nList, GUIntBig* pList) {(int nDims2, GUIntBig *count)};
413 %apply (int nList, GIntBig* pList) {(int nDims3, GIntBig *array_step)};
414 %apply (int nList, GIntBig* pList) {(int nDims4, GIntBig *buffer_stride)};
Read(int nDims1,GUIntBig * array_start_idx,int nDims2,GUIntBig * count,int nDims3,GIntBig * array_step,int nDims4,GIntBig * buffer_stride,GDALExtendedDataTypeHS * buffer_datatype,void ** buf)415   CPLErr Read( int nDims1, GUIntBig* array_start_idx,
416                int nDims2, GUIntBig* count,
417                int nDims3, GIntBig* array_step,
418                int nDims4, GIntBig* buffer_stride,
419                GDALExtendedDataTypeHS* buffer_datatype,
420                void **buf) {
421     *buf = NULL;
422 
423     size_t buf_size = 0;
424     if( MDArrayReadWriteCheckArguments(self, true,
425                                         nDims1, array_start_idx,
426                                         nDims2, count,
427                                         nDims3, array_step,
428                                         nDims4, buffer_stride,
429                                         buffer_datatype,
430                                         &buf_size) != CE_None )
431     {
432       return CE_Failure;
433     }
434 
435     const int nExpectedDims = (int)GDALMDArrayGetDimensionCount(self);
436     std::vector<size_t> count_internal(nExpectedDims + 1);
437     std::vector<GPtrDiff_t> buffer_stride_internal(nExpectedDims + 1);
438     size_t nProductCount = 1;
439     for( int i = 0; i < nExpectedDims; i++ )
440     {
441         count_internal[i] = (size_t)count[i];
442         if( count_internal[i] != count[i] )
443         {
444             CPLError(CE_Failure, CPLE_AppDefined, "Integer overflow");
445             return CE_Failure;
446         }
447         nProductCount *= count_internal[i];
448         buffer_stride_internal[i] = (GPtrDiff_t)buffer_stride[i];
449         if( buffer_stride_internal[i] != buffer_stride[i] )
450         {
451             CPLError(CE_Failure, CPLE_AppDefined, "Integer overflow");
452             return CE_Failure;
453         }
454     }
455 
456     GDALExtendedDataTypeHS* selfType = GDALMDArrayGetDataType(self);
457     bool isSelfString = GDALExtendedDataTypeGetClass(selfType) == GEDTC_STRING;
458     GDALExtendedDataTypeRelease(selfType);
459 
460     if( GDALExtendedDataTypeGetClass(buffer_datatype) == GEDTC_STRING &&
461         isSelfString )
462     {
463         size_t nExpectedStride = 1;
464         for( int i = nExpectedDims; i > 0; )
465         {
466             --i;
467             if( (size_t)buffer_stride_internal[i] != nExpectedStride )
468             {
469                 CPLError(CE_Failure, CPLE_AppDefined, "Unhandled stride");
470                 return CE_Failure;
471             }
472             nExpectedStride *= count_internal[i];
473         }
474         char** ppszBuffer = (char**)VSI_CALLOC_VERBOSE(nProductCount, sizeof(char*));
475         if( !ppszBuffer )
476             return CE_Failure;
477         GByte* pabyBuffer = (GByte*)ppszBuffer;
478         if( !(GDALMDArrayRead( self,
479                             array_start_idx,
480                             &count_internal[0],
481                             array_step,
482                             NULL,
483                             buffer_datatype,
484                             pabyBuffer,
485                             pabyBuffer,
486                             nProductCount * sizeof(char*) )) )
487         {
488             for( size_t i = 0; i < nProductCount; i++ )
489                 VSIFree(ppszBuffer[i]);
490             VSIFree(pabyBuffer);
491             return CE_Failure;
492         }
493 
494         SWIG_PYTHON_THREAD_BEGIN_BLOCK;
495         PyObject* obj = PyList_New( nProductCount );
496         for( size_t i = 0; i < nProductCount; i++ )
497         {
498             if( !ppszBuffer[i] )
499             {
500                 Py_INCREF(Py_None);
501                 PyList_SetItem(obj, i, Py_None);
502             }
503             else
504             {
505                 PyList_SetItem(obj, i, GDALPythonObjectFromCStr( ppszBuffer[i] ) );
506             }
507             VSIFree(ppszBuffer[i]);
508         }
509         SWIG_PYTHON_THREAD_END_BLOCK;
510         *buf = obj;
511         VSIFree(pabyBuffer);
512         return CE_None;
513     }
514 
515     if( MDArrayReadWriteCheckArguments(self, false,
516                                         nDims1, array_start_idx,
517                                         nDims2, count,
518                                         nDims3, array_step,
519                                         nDims4, buffer_stride,
520                                         buffer_datatype,
521                                         &buf_size) != CE_None )
522     {
523       return CE_Failure;
524     }
525     if( buf_size == 0 )
526     {
527         return CE_None;
528     }
529 
530 
531     SWIG_PYTHON_THREAD_BEGIN_BLOCK;
532     *buf = (void *)PyByteArray_FromStringAndSize( NULL, buf_size );
533     if (*buf == NULL)
534     {
535         *buf = Py_None;
536         if( !bUseExceptions )
537         {
538             PyErr_Clear();
539         }
540         SWIG_PYTHON_THREAD_END_BLOCK;
541         CPLError(CE_Failure, CPLE_OutOfMemory, "Cannot allocate result buffer");
542         return CE_Failure;
543     }
544     char *data = PyByteArray_AsString( (PyObject *)*buf );
545     SWIG_PYTHON_THREAD_END_BLOCK;
546 
547     memset(data, 0, buf_size);
548 
549     CPLErr eErr = GDALMDArrayRead( self,
550                                    array_start_idx,
551                                    &count_internal[0],
552                                    array_step,
553                                    &buffer_stride_internal[0],
554                                    buffer_datatype,
555                                    data,
556                                    data,
557                                    buf_size ) ? CE_None : CE_Failure;
558     if (eErr == CE_Failure)
559     {
560         SWIG_PYTHON_THREAD_BEGIN_BLOCK;
561         Py_DECREF((PyObject*)*buf);
562         SWIG_PYTHON_THREAD_END_BLOCK;
563         *buf = NULL;
564     }
565 
566     return eErr;
567   }
568 %clear (void **buf );
569 
WriteStringArray(int nDims1,GUIntBig * array_start_idx,int nDims2,GUIntBig * count,int nDims3,GIntBig * array_step,GDALExtendedDataTypeHS * buffer_datatype,char ** options)570   CPLErr WriteStringArray( int nDims1, GUIntBig* array_start_idx,
571                int nDims2, GUIntBig* count,
572                int nDims3, GIntBig* array_step,
573                GDALExtendedDataTypeHS* buffer_datatype,
574                char** options)
575   {
576 
577     const int nExpectedDims = (int)GDALMDArrayGetDimensionCount(self);
578     std::vector<size_t> count_internal(nExpectedDims);
579     if( nExpectedDims != 1 )
580     {
581         CPLError(CE_Failure, CPLE_AppDefined,
582             "Unsupported number of dimensions");
583         return CE_Failure;
584     }
585     for( int i = 0; i < nExpectedDims; i++ )
586     {
587         count_internal[i] = (size_t)count[i];
588         if( count_internal[i] != count[i] )
589         {
590             CPLError(CE_Failure, CPLE_AppDefined, "Integer overflow");
591             return CE_Failure;
592         }
593     }
594     if( nDims1 != 1 )
595     {
596         CPLError(CE_Failure, CPLE_AppDefined,
597             "Wrong number of values in array_start_idx");
598         return CE_Failure;
599     }
600     if( nDims2 != 1 )
601     {
602         CPLError(CE_Failure, CPLE_AppDefined,
603             "Wrong number of values in count");
604         return CE_Failure;
605     }
606     if( nDims3 != 1 )
607     {
608         CPLError(CE_Failure, CPLE_AppDefined,
609             "Wrong number of values in array_step");
610         return CE_Failure;
611     }
612 
613     CPLErr eErr = GDALMDArrayWrite(self,
614                                    array_start_idx,
615                                    &count_internal[0],
616                                    array_step,
617                                    NULL,
618                                    buffer_datatype,
619                                    options,
620                                    options,
621                                    CSLCount(options) * sizeof(char*) ) ? CE_None : CE_Failure;
622     return eErr;
623   }
624 
625 
626 %apply Pointer NONNULL {GDALExtendedDataTypeHS* buffer_datatype};
627 %apply (GIntBig nLen, char *pBuf) { (GIntBig buf_len, char *buf_string) };
628 %apply (int nList, GUIntBig* pList) {(int nDims1, GUIntBig *array_start_idx)};
629 %apply (int nList, GUIntBig* pList) {(int nDims2, GUIntBig *count)};
630 %apply (int nList, GIntBig* pList) {(int nDims3, GIntBig *array_step)};
631 %apply (int nList, GIntBig* pList) {(int nDims4, GIntBig *buffer_stride)};
Write(int nDims1,GUIntBig * array_start_idx,int nDims2,GUIntBig * count,int nDims3,GIntBig * array_step,int nDims4,GIntBig * buffer_stride,GDALExtendedDataTypeHS * buffer_datatype,GIntBig buf_len,char * buf_string)632   CPLErr Write( int nDims1, GUIntBig* array_start_idx,
633                int nDims2, GUIntBig* count,
634                int nDims3, GIntBig* array_step,
635                int nDims4, GIntBig* buffer_stride,
636                GDALExtendedDataTypeHS* buffer_datatype,
637                GIntBig buf_len, char *buf_string) {
638 
639     size_t buf_size = 0;
640     if( MDArrayReadWriteCheckArguments(self, false,
641                                         nDims1, array_start_idx,
642                                         nDims2, count,
643                                         nDims3, array_step,
644                                         nDims4, buffer_stride,
645                                         buffer_datatype,
646                                         &buf_size) != CE_None )
647     {
648       return CE_Failure;
649     }
650 
651     if ( (GUIntBig)buf_len < buf_size )
652     {
653         CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
654         return CE_Failure;
655     }
656 
657     const int nExpectedDims = (int)GDALMDArrayGetDimensionCount(self);
658     std::vector<size_t> count_internal(nExpectedDims+1);
659     std::vector<GPtrDiff_t> buffer_stride_internal(nExpectedDims+1);
660     for( int i = 0; i < nExpectedDims; i++ )
661     {
662         count_internal[i] = (size_t)count[i];
663         if( count_internal[i] != count[i] )
664         {
665             CPLError(CE_Failure, CPLE_AppDefined, "Integer overflow");
666             return CE_Failure;
667         }
668         buffer_stride_internal[i] = (GPtrDiff_t)buffer_stride[i];
669         if( buffer_stride_internal[i] != buffer_stride[i] )
670         {
671             CPLError(CE_Failure, CPLE_AppDefined, "Integer overflow");
672             return CE_Failure;
673         }
674     }
675 
676     CPLErr eErr = GDALMDArrayWrite( self,
677                                    array_start_idx,
678                                    &count_internal[0],
679                                    array_step,
680                                    &buffer_stride_internal[0],
681                                    buffer_datatype,
682                                    buf_string,
683                                    buf_string,
684                                    (size_t)buf_len ) ? CE_None : CE_Failure;
685     return eErr;
686   }
687 %clear (void **buf );
688 
689 
690 %apply (int nList, GUIntBig* pList) {(int nDims1, GUIntBig *array_start_idx)};
691 %apply (int nList, GUIntBig* pList) {(int nDims2, GUIntBig *count)};
AdviseRead(int nDims1,GUIntBig * array_start_idx,int nDims2,GUIntBig * count)692   CPLErr AdviseRead( int nDims1, GUIntBig* array_start_idx,
693                      int nDims2, GUIntBig* count ) {
694 
695     const int nExpectedDims = (int)GDALMDArrayGetDimensionCount(self);
696     if( nDims1 != nExpectedDims )
697     {
698         CPLError(CE_Failure, CPLE_AppDefined,
699             "Wrong number of values in array_start_idx");
700         return CE_Failure;
701     }
702     if( nDims2 != nExpectedDims )
703     {
704         CPLError(CE_Failure, CPLE_AppDefined,
705             "Wrong number of values in count");
706         return CE_Failure;
707     }
708 
709     std::vector<size_t> count_internal(nExpectedDims+1);
710     for( int i = 0; i < nExpectedDims; i++ )
711     {
712         count_internal[i] = (size_t)count[i];
713         if( count_internal[i] != count[i] )
714         {
715             CPLError(CE_Failure, CPLE_AppDefined, "Integer overflow");
716             return CE_Failure;
717         }
718     }
719 
720     if( !(GDALMDArrayAdviseRead( self, array_start_idx, count_internal.data() )) )
721     {
722         return CE_Failure;
723     }
724     return CE_None;
725   }
726 #endif
727 
728 %newobject GetAttribute;
GetAttribute(const char * name)729   GDALAttributeHS* GetAttribute( const char* name) {
730     return GDALMDArrayGetAttribute(self, name);
731   }
732 
733 #if defined(SWIGPYTHON)
734   void GetAttributes( GDALAttributeHS*** pattrs, size_t* pnCount, char** options = 0 ) {
735     *pattrs = GDALMDArrayGetAttributes(self, pnCount, options);
736   }
737 #endif
738 
739 %newobject CreateAttribute;
740 %apply (int nList, GUIntBig* pList) {(int nDimensions, GUIntBig *dimensions)};
741   GDALAttributeHS *CreateAttribute( const char *name,
742                                     int nDimensions,
743                                     GUIntBig *dimensions,
744                                     GDALExtendedDataTypeHS* data_type,
745                                     char **options = 0)
746   {
747     return GDALMDArrayCreateAttribute(self, name, nDimensions,
748                                     (const GUInt64*)dimensions,
749                                     data_type, options);
750   }
751 
752 #if defined(SWIGPYTHON)
753 %apply ( void **outPythonObject ) { (void **buf ) };
GetNoDataValueAsRaw(void ** buf)754   CPLErr GetNoDataValueAsRaw( void **buf) {
755     *buf = NULL;
756     const void* pabyBuf = GDALMDArrayGetRawNoDataValue(self);
757     if( pabyBuf == NULL )
758     {
759       return CE_Failure;
760     }
761     GDALExtendedDataTypeHS* selfType = GDALMDArrayGetDataType(self);
762     const size_t buf_size = GDALExtendedDataTypeGetSize(selfType);
763     GDALExtendedDataTypeRelease(selfType);
764 
765     SWIG_PYTHON_THREAD_BEGIN_BLOCK;
766     *buf = (void *)PyByteArray_FromStringAndSize( NULL, buf_size );
767     if (*buf == NULL)
768     {
769         *buf = Py_None;
770         if( !bUseExceptions )
771         {
772             PyErr_Clear();
773         }
774         SWIG_PYTHON_THREAD_END_BLOCK;
775         CPLError(CE_Failure, CPLE_OutOfMemory, "Cannot allocate result buffer");
776         return CE_Failure;
777     }
778     char *data = PyByteArray_AsString( (PyObject *)*buf );
779     SWIG_PYTHON_THREAD_END_BLOCK;
780 
781     memcpy(data, pabyBuf, buf_size);
782 
783     return CE_None;
784   }
785 %clear (void **buf );
786 #endif
787 
GetNoDataValueAsDouble(double * val,int * hasval)788   void GetNoDataValueAsDouble( double *val, int *hasval ) {
789     *val = GDALMDArrayGetNoDataValueAsDouble( self, hasval );
790   }
791 
SetNoDataValueDouble(double d)792   CPLErr SetNoDataValueDouble( double d ) {
793     return GDALMDArraySetNoDataValueAsDouble( self, d ) ? CE_None : CE_Failure;
794   }
795 
796 #if defined(SWIGPYTHON)
SetNoDataValueRaw(GIntBig nLen,char * pBuf)797   CPLErr SetNoDataValueRaw(GIntBig nLen, char *pBuf)
798   {
799     GDALExtendedDataTypeHS* selfType = GDALMDArrayGetDataType(self);
800     const size_t selfTypeSize = GDALExtendedDataTypeGetSize(selfType);
801     GDALExtendedDataTypeRelease(selfType);
802 
803     if( static_cast<size_t>(nLen) != selfTypeSize )
804     {
805         CPLError(CE_Failure, CPLE_IllegalArg, "Argument of wrong size");
806         return CE_Failure;
807     }
808     return GDALMDArraySetRawNoDataValue(self, pBuf) ? CE_None : CE_Failure;
809   }
810 #endif
811 
DeleteNoDataValue()812   CPLErr DeleteNoDataValue() {
813     return GDALMDArraySetRawNoDataValue( self, NULL ) ? CE_None : CE_Failure;
814   }
815 
GetOffset(double * val,int * hasval)816   void GetOffset( double *val, int *hasval ) {
817     *val = GDALMDArrayGetOffset( self, hasval );
818   }
819 
GetOffsetStorageType()820   GDALDataType GetOffsetStorageType() {
821     GDALDataType eDT = GDT_Unknown;
822     int hasval = FALSE;
823     GDALMDArrayGetOffsetEx( self, &hasval, &eDT );
824     return hasval ? eDT : GDT_Unknown;
825   }
826 
GetScale(double * val,int * hasval)827   void GetScale( double *val, int *hasval ) {
828     *val = GDALMDArrayGetScale( self, hasval );
829   }
830 
GetScaleStorageType()831   GDALDataType GetScaleStorageType() {
832     GDALDataType eDT = GDT_Unknown;
833     int hasval = FALSE;
834     GDALMDArrayGetScaleEx( self, &hasval, &eDT );
835     return hasval ? eDT : GDT_Unknown;
836   }
837 
838 %feature ("kwargs") SetOffset;
839   CPLErr SetOffset( double val, GDALDataType storageType = GDT_Unknown ) {
840     return GDALMDArraySetOffsetEx( self, val, storageType ) ? CE_None : CE_Failure;
841   }
842 
843 %feature ("kwargs") SetScale;
844   CPLErr SetScale( double val, GDALDataType storageType = GDT_Unknown ) {
845     return GDALMDArraySetScaleEx( self, val, storageType ) ? CE_None : CE_Failure;
846   }
847 
SetUnit(const char * unit)848   CPLErr SetUnit(const char* unit) {
849     return GDALMDArraySetUnit(self, unit) ? CE_None : CE_Failure;
850   }
851 
GetUnit()852   const char* GetUnit() {
853     return GDALMDArrayGetUnit(self);
854   }
855 
856 #ifndef SWIGCSHARP
SetSpatialRef(OSRSpatialReferenceShadow * srs)857   OGRErr SetSpatialRef(OSRSpatialReferenceShadow* srs)
858   {
859      return GDALMDArraySetSpatialRef( self, (OGRSpatialReferenceH)srs ) ? CE_None : CE_Failure;
860   }
861 
862   %newobject GetSpatialRef;
GetSpatialRef()863   OSRSpatialReferenceShadow *GetSpatialRef() {
864     return GDALMDArrayGetSpatialRef(self);
865   }
866 #endif
867 
868 %newobject GetView;
869 %apply Pointer NONNULL {const char* viewExpr};
GetView(const char * viewExpr)870   GDALMDArrayHS* GetView(const char* viewExpr)
871   {
872     return GDALMDArrayGetView(self, viewExpr);
873   }
874 
875 %newobject Transpose;
Transpose(int nList,int * pList)876   GDALMDArrayHS* Transpose(int nList, int* pList)
877   {
878     return GDALMDArrayTranspose(self, nList, pList);
879   }
880 
881 %newobject GetUnscaled;
GetUnscaled()882   GDALMDArrayHS* GetUnscaled()
883   {
884     return GDALMDArrayGetUnscaled(self);
885   }
886 
887 %newobject GetMask;
888 %apply (char **CSL) {char **};
889   GDALMDArrayHS* GetMask(char** options = 0)
890   {
891     return GDALMDArrayGetMask(self, options);
892   }
893 %clear char **;
894 
895 %newobject AsClassicDataset;
AsClassicDataset(size_t iXDim,size_t iYDim)896   GDALDatasetShadow* AsClassicDataset(size_t iXDim, size_t iYDim)
897   {
898     return (GDALDatasetShadow*)GDALMDArrayAsClassicDataset(self, iXDim, iYDim);
899   }
900 
901 #ifndef SWIGCSHARP
902 %newobject Statistics;
903 %feature ("kwargs") GetStatistics;
904   Statistics* GetStatistics( GDALDatasetShadow* ds = NULL,
905                              bool approx_ok = FALSE,
906                              bool force = TRUE,
907                              GDALProgressFunc callback = NULL,
908                              void* callback_data=NULL)
909   {
910         GUInt64 nValidCount = 0;
911         Statistics* psStatisticsOut = (Statistics*)CPLMalloc(sizeof(Statistics));
912         CPLErr eErr = GDALMDArrayGetStatistics(self, ds, approx_ok, force,
913                                  &(psStatisticsOut->min),
914                                  &(psStatisticsOut->max),
915                                  &(psStatisticsOut->mean),
916                                  &(psStatisticsOut->std_dev),
917                                  &nValidCount,
918                                  callback, callback_data);
919         psStatisticsOut->valid_count = static_cast<GIntBig>(nValidCount);
920         if( eErr == CE_None )
921             return psStatisticsOut;
922         CPLFree(psStatisticsOut);
923         return NULL;
924   }
925 
926 %newobject Statistics;
927 %feature ("kwargs") ComputeStatistics;
928   Statistics* ComputeStatistics( GDALDatasetShadow* ds = NULL,
929                                  bool approx_ok = FALSE,
930                                  GDALProgressFunc callback = NULL,
931                                  void* callback_data=NULL)
932   {
933         GUInt64 nValidCount = 0;
934         Statistics* psStatisticsOut = (Statistics*)CPLMalloc(sizeof(Statistics));
935         int nSuccess = GDALMDArrayComputeStatistics(self, ds, approx_ok,
936                                  &(psStatisticsOut->min),
937                                  &(psStatisticsOut->max),
938                                  &(psStatisticsOut->mean),
939                                  &(psStatisticsOut->std_dev),
940                                  &nValidCount,
941                                  callback, callback_data);
942         psStatisticsOut->valid_count = static_cast<GIntBig>(nValidCount);
943         if( nSuccess )
944             return psStatisticsOut;
945         CPLFree(psStatisticsOut);
946         return NULL;
947   }
948 #endif
949 
950 } /* extend */
951 }; /* GDALMDArrayH */
952 
953 
954 //************************************************************************
955 //
956 // GDALAttribute
957 //
958 //************************************************************************
959 
960 %rename (Attribute) GDALAttributeHS;
961 
962 class GDALAttributeHS {
963 private:
964   GDALAttributeHS();
965 public:
966 %extend {
967 
~GDALAttributeHS()968   ~GDALAttributeHS() {
969     GDALAttributeRelease(self);
970   }
971 
GetName()972   const char* GetName() {
973     return GDALAttributeGetName(self);
974   }
975 
GetFullName()976   const char* GetFullName() {
977     return GDALAttributeGetFullName(self);
978   }
979 
GetTotalElementsCount()980   unsigned long long GetTotalElementsCount() {
981     return GDALAttributeGetTotalElementsCount(self);
982   }
983 
GetDimensionCount()984   size_t GetDimensionCount() {
985     return GDALAttributeGetDimensionCount(self);
986   }
987 
988 #if defined(SWIGPYTHON)
989 %apply ( GUIntBig** pvals, size_t* pnCount ) { (GUIntBig** pdims, size_t* pnCount ) };
GetDimensionsSize(GUIntBig ** pdims,size_t * pnCount)990   void GetDimensionsSize( GUIntBig** pdims, size_t* pnCount ) {
991     *pdims = GDALAttributeGetDimensionsSize(self, pnCount);
992   }
993 #endif
994 
995 %newobject GetDataType;
GetDataType()996   GDALExtendedDataTypeHS* GetDataType() {
997     return GDALAttributeGetDataType(self);
998   }
999 
1000 #if defined(SWIGPYTHON)
1001 %apply ( void **outPythonObject ) { (void **buf ) };
ReadAsRaw(void ** buf)1002   CPLErr ReadAsRaw( void **buf) {
1003     *buf = NULL;
1004     GDALExtendedDataTypeHS* dt = GDALAttributeGetDataType(self);
1005     bool bIsNumeric = CheckNumericDataType(dt);
1006     GDALExtendedDataTypeRelease(dt);
1007     if( !bIsNumeric )
1008     {
1009         CPLError(CE_Failure, CPLE_NotSupported,
1010             "non-numeric buffer data type not supported in SWIG bindings");
1011         return CE_Failure;
1012     }
1013     size_t buf_size = 0;
1014     GByte* pabyBuf = GDALAttributeReadAsRaw(self, &buf_size);
1015     if( pabyBuf == NULL )
1016     {
1017       return CE_Failure;
1018     }
1019 
1020     SWIG_PYTHON_THREAD_BEGIN_BLOCK;
1021     *buf = (void *)PyBytes_FromStringAndSize( NULL, buf_size );
1022     if (*buf == NULL)
1023     {
1024         *buf = Py_None;
1025         if( !bUseExceptions )
1026         {
1027             PyErr_Clear();
1028         }
1029         SWIG_PYTHON_THREAD_END_BLOCK;
1030         CPLError(CE_Failure, CPLE_OutOfMemory, "Cannot allocate result buffer");
1031         GDALAttributeFreeRawResult(self, pabyBuf, buf_size);
1032         return CE_Failure;
1033     }
1034     char *data = PyBytes_AsString( (PyObject *)*buf );
1035     SWIG_PYTHON_THREAD_END_BLOCK;
1036 
1037     memcpy(data, pabyBuf, buf_size);
1038     GDALAttributeFreeRawResult(self, pabyBuf, buf_size);
1039 
1040     return CE_None;
1041   }
1042 %clear (void **buf );
1043 #endif
1044 
ReadAsString()1045   const char* ReadAsString() {
1046     return GDALAttributeReadAsString(self);
1047   }
1048 
ReadAsInt()1049   int ReadAsInt() {
1050     return GDALAttributeReadAsInt(self);
1051   }
1052 
ReadAsDouble()1053   double ReadAsDouble() {
1054     return GDALAttributeReadAsDouble(self);
1055   }
1056 
1057 %apply (char **CSL) {char **};
ReadAsStringArray()1058   char** ReadAsStringArray() {
1059     return GDALAttributeReadAsStringArray(self);
1060   }
1061 %clear char **;
1062 
1063 #if defined(SWIGPYTHON)
ReadAsIntArray(int ** pvals,size_t * pnCount)1064   void ReadAsIntArray( int** pvals, size_t* pnCount ) {
1065     *pvals = GDALAttributeReadAsIntArray(self, pnCount);
1066   }
1067 #endif
1068 
1069 #if defined(SWIGPYTHON)
ReadAsDoubleArray(double ** pvals,size_t * pnCount)1070   void ReadAsDoubleArray( double** pvals, size_t* pnCount ) {
1071     *pvals = GDALAttributeReadAsDoubleArray(self, pnCount);
1072   }
1073 #endif
1074 
1075 #if defined(SWIGPYTHON)
WriteRaw(GIntBig nLen,char * pBuf)1076   CPLErr WriteRaw(GIntBig nLen, char *pBuf)
1077   {
1078     GDALExtendedDataTypeHS* dt = GDALAttributeGetDataType(self);
1079     bool bIsNumeric = CheckNumericDataType(dt);
1080     GDALExtendedDataTypeRelease(dt);
1081     if( !bIsNumeric )
1082     {
1083         CPLError(CE_Failure, CPLE_NotSupported,
1084             "non-numeric buffer data type not supported in SWIG bindings");
1085         return CE_Failure;
1086     }
1087     return GDALAttributeWriteRaw(self, pBuf, nLen) ? CE_None : CE_Failure;
1088   }
1089 #endif
1090 
WriteString(const char * val)1091   CPLErr WriteString(const char* val)
1092   {
1093     return GDALAttributeWriteString(self, val) ? CE_None : CE_Failure;
1094   }
1095 
1096 %apply (char **options ) { (char **vals) };
WriteStringArray(char ** vals)1097   CPLErr WriteStringArray(char** vals)
1098   {
1099     return GDALAttributeWriteStringArray(self, vals) ? CE_None : CE_Failure;
1100   }
1101 %clear (char **vals);
1102 
WriteInt(int val)1103   CPLErr WriteInt(int val)
1104   {
1105     return GDALAttributeWriteInt(self, val) ? CE_None : CE_Failure;
1106   }
1107 
WriteDouble(double val)1108   CPLErr WriteDouble(double val)
1109   {
1110     return GDALAttributeWriteDouble(self, val) ? CE_None : CE_Failure;
1111   }
1112 
1113 #if defined(SWIGPYTHON)
WriteDoubleArray(int nList,double * pList)1114   CPLErr WriteDoubleArray(int nList, double* pList)
1115   {
1116     return GDALAttributeWriteDoubleArray(self, pList, nList) ? CE_None : CE_Failure;
1117   }
1118 #endif
1119 
1120 } /* extend */
1121 }; /* GDALAttributeH */
1122 
1123 
1124 //************************************************************************
1125 //
1126 // GDALDimension
1127 //
1128 //************************************************************************
1129 
1130 %rename (Dimension) GDALDimensionHS;
1131 
1132 class GDALDimensionHS {
1133 private:
1134   GDALDimensionHS();
1135 public:
1136 %extend {
1137 
~GDALDimensionHS()1138   ~GDALDimensionHS() {
1139     GDALDimensionRelease(self);
1140   }
1141 
GetName()1142   const char* GetName() {
1143     return GDALDimensionGetName(self);
1144   }
1145 
GetFullName()1146   const char* GetFullName() {
1147     return GDALDimensionGetFullName(self);
1148   }
1149 
1150 #if defined(SWIGCSHARP)
GetType_()1151   const char* GetType_()
1152 #else
1153   const char* GetType()
1154 #endif
1155   {
1156     return GDALDimensionGetType(self);
1157   }
1158 
GetDirection()1159   const char* GetDirection() {
1160     return GDALDimensionGetDirection(self);
1161   }
1162 
GetSize()1163   unsigned long long GetSize() {
1164     return GDALDimensionGetSize(self);
1165   }
1166 
1167 %newobject GetIndexingVariable;
GetIndexingVariable()1168   GDALMDArrayHS* GetIndexingVariable() {
1169     return GDALDimensionGetIndexingVariable(self);
1170   }
1171 
SetIndexingVariable(GDALMDArrayHS * array)1172   bool SetIndexingVariable(GDALMDArrayHS* array) {
1173     return GDALDimensionSetIndexingVariable(self, array);
1174   }
1175 
1176 } /* extend */
1177 }; /* GDALDimensionH */
1178 
1179 
1180 //************************************************************************
1181 //
1182 // GDALExtendedDataTypeClass
1183 //
1184 //************************************************************************
1185 
1186 %rename (ExtendedDataTypeClass) GDALExtendedDataTypeClass;
1187 
1188 typedef enum {
1189     GEDTC_NUMERIC,
1190     GEDTC_STRING,
1191     GEDTC_COMPOUND
1192 } GDALExtendedDataTypeClass;
1193 
1194 //************************************************************************
1195 //
1196 // GDALExtendedDataType
1197 //
1198 //************************************************************************
1199 
1200 %rename (ExtendedDataType) GDALExtendedDataTypeHS;
1201 
1202 class GDALExtendedDataTypeHS {
1203 private:
1204   GDALExtendedDataTypeHS();
1205 public:
1206 %extend {
1207 
~GDALExtendedDataTypeHS()1208   ~GDALExtendedDataTypeHS() {
1209     GDALExtendedDataTypeRelease(self);
1210   }
1211 
1212 %newobject Create;
Create(GDALDataType dt)1213   static GDALExtendedDataTypeHS* Create(GDALDataType dt)
1214   {
1215     return GDALExtendedDataTypeCreate(dt);
1216   }
1217 
1218 %newobject CreateString;
1219   static GDALExtendedDataTypeHS* CreateString(size_t nMaxStringLength = 0)
1220   {
1221     return GDALExtendedDataTypeCreateString(nMaxStringLength);
1222   }
1223 
1224 #if defined(SWIGPYTHON)
1225 %newobject CreateCompound;
1226 %apply (int object_list_count, GDALEDTComponentHS **poObjects) {(int nComps, GDALEDTComponentHS **comps)};
CreateCompound(const char * name,size_t nTotalSize,int nComps,GDALEDTComponentHS ** comps)1227   static GDALExtendedDataTypeHS* CreateCompound(const char* name,
1228                                                 size_t nTotalSize,
1229                                                 int nComps,
1230                                                 GDALEDTComponentHS** comps)
1231   {
1232     return GDALExtendedDataTypeCreateCompound(name, nTotalSize, nComps, comps);
1233   }
1234 %clear (int nComps, GDALEDTComponentHS **comps);
1235 #endif
1236 
GetName()1237   const char* GetName()
1238   {
1239     return GDALExtendedDataTypeGetName(self);
1240   }
1241 
GetClass()1242   GDALExtendedDataTypeClass GetClass()
1243   {
1244     return GDALExtendedDataTypeGetClass(self);
1245   }
1246 
GetNumericDataType()1247   GDALDataType GetNumericDataType()
1248   {
1249     return GDALExtendedDataTypeGetNumericDataType(self);
1250   }
1251 
GetSize()1252   size_t GetSize()
1253   {
1254     return GDALExtendedDataTypeGetSize(self);
1255   }
1256 
GetMaxStringLength()1257   size_t GetMaxStringLength()
1258   {
1259     return GDALExtendedDataTypeGetMaxStringLength(self);
1260   }
1261 
1262 #if defined(SWIGPYTHON)
GetComponents(GDALEDTComponentHS *** pcomps,size_t * pnCount)1263   void GetComponents( GDALEDTComponentHS*** pcomps, size_t* pnCount ) {
1264     *pcomps = GDALExtendedDataTypeGetComponents(self, pnCount);
1265   }
1266 #endif
1267 
1268 %apply Pointer NONNULL {GDALExtendedDataTypeHS* other};
CanConvertTo(GDALExtendedDataTypeHS * other)1269   bool CanConvertTo(GDALExtendedDataTypeHS* other)
1270   {
1271     return GDALExtendedDataTypeCanConvertTo(self, other);
1272   }
1273 
Equals(GDALExtendedDataTypeHS * other)1274   bool Equals(GDALExtendedDataTypeHS* other)
1275   {
1276     return GDALExtendedDataTypeEquals(self, other);
1277   }
1278 
1279 } /* extend */
1280 }; /* GDALExtendedDataTypeH */
1281 
1282 
1283 //************************************************************************
1284 //
1285 // GDALExtendedDataType
1286 //
1287 //************************************************************************
1288 
1289 %rename (EDTComponent) GDALEDTComponentHS;
1290 
1291 class GDALEDTComponentHS {
1292 private:
1293   GDALEDTComponentHS();
1294 public:
1295 %extend {
1296 
~GDALEDTComponentHS()1297   ~GDALEDTComponentHS() {
1298     GDALEDTComponentRelease(self);
1299   }
1300 
1301 %newobject Create;
1302 %apply Pointer NONNULL {const char* name};
1303 %apply Pointer NONNULL {GDALExtendedDataTypeHS* type};
Create(const char * name,size_t offset,GDALExtendedDataTypeHS * type)1304   static GDALEDTComponentHS* Create(const char* name, size_t offset, GDALExtendedDataTypeHS* type)
1305   {
1306     return GDALEDTComponentCreate(name, offset, type);
1307   }
1308 
GetName()1309   const char* GetName()
1310   {
1311     return GDALEDTComponentGetName(self);
1312   }
1313 
GetOffset()1314   size_t GetOffset()
1315   {
1316     return GDALEDTComponentGetOffset(self);
1317   }
1318 
1319 #if defined(SWIGCSHARP)
1320 %newobject GetType_;
GetType_()1321   GDALExtendedDataTypeHS* GetType_()
1322 #else
1323 %newobject GetType;
1324   GDALExtendedDataTypeHS* GetType()
1325 #endif
1326   {
1327     return GDALEDTComponentGetType(self);
1328   }
1329 
1330 
1331 } /* extend */
1332 }; /* GDALEDTComponentHS */
1333 
1334