1 /******************************************************************************
2  * $Id: cpl.i cf9f034edfd3b434038b18d748dae6cdb38c2eb9 2021-03-16 15:11:39 +0100 Even Rouault $
3  *
4  * Name:     cpl.i
5  * Project:  GDAL Python Interface
6  * Purpose:  GDAL Core SWIG Interface declarations.
7  * Author:   Kevin Ruland, kruland@ku.edu
8  *
9  ******************************************************************************
10  * Copyright (c) 2005, Kevin Ruland
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  *****************************************************************************/
30 
31 %include constraints.i
32 
33 #ifdef SWIGCSHARP
34 typedef enum
35 {
36     CE_None = 0,
37     CE_Log = 1,
38     CE_Warning = 2,
39     CE_Failure = 3,
40     CE_Fatal = 4
41 } CPLErr;
42 #endif
43 
44 %inline %{
45 typedef char retStringAndCPLFree;
46 %}
47 
48 %apply Pointer NONNULL {const char *message};
49 %inline %{
Debug(const char * msg_class,const char * message)50   void Debug( const char *msg_class, const char *message ) {
51     CPLDebug( msg_class, "%s", message );
52   }
53 %}
54 %clear (const char *message);
55 
56 %inline %{
57   CPLErr SetErrorHandler( CPLErrorHandler pfnErrorHandler = NULL, void* user_data = NULL )
58   {
59     if( pfnErrorHandler == NULL )
60     {
61         pfnErrorHandler = CPLDefaultErrorHandler;
62     }
63 
64     CPLSetErrorHandlerEx( pfnErrorHandler, user_data );
65 
66     return CE_None;
67   }
68 %}
69 
70 %rename (SetCurrentErrorHandlerCatchDebug) CPLSetCurrentErrorHandlerCatchDebug;
71 void CPLSetCurrentErrorHandlerCatchDebug( int bCatchDebug );
72 
73 #ifdef SWIGPYTHON
74 
75 %nothread;
76 
77 %{
78 extern "C" int CPL_DLL GDALIsInGlobalDestructor();
79 
PyCPLErrorHandler(CPLErr eErrClass,int err_no,const char * pszErrorMsg)80 void CPL_STDCALL PyCPLErrorHandler(CPLErr eErrClass, int err_no, const char* pszErrorMsg)
81 {
82     if( GDALIsInGlobalDestructor() )
83     {
84         // this is typically during Python interpreter shutdown, and ends up in a crash
85         // because error handling tries to do thread initialization.
86         return;
87     }
88 
89     void* user_data = CPLGetErrorHandlerUserData();
90     PyObject *psArgs;
91 
92     SWIG_PYTHON_THREAD_BEGIN_BLOCK;
93 
94     psArgs = Py_BuildValue("(iis)", eErrClass, err_no, pszErrorMsg );
95     PyObject_CallObject( (PyObject*)user_data, psArgs);
96     Py_XDECREF(psArgs);
97 
98     SWIG_PYTHON_THREAD_END_BLOCK;
99 }
100 %}
101 
102 %inline %{
103   CPLErr PushErrorHandler( CPLErrorHandler pfnErrorHandler = NULL, void* user_data = NULL )
104   {
105     if( pfnErrorHandler == NULL )
106         CPLPushErrorHandler(CPLQuietErrorHandler);
107     else
108         CPLPushErrorHandlerEx(pfnErrorHandler, user_data);
109     return CE_None;
110   }
111 %}
112 
113 %inline %{
PopErrorHandler()114   void PopErrorHandler()
115   {
116      void* user_data = CPLGetErrorHandlerUserData();
117      if( user_data != NULL )
118      {
119          Py_XDECREF((PyObject*)user_data);
120      }
121      CPLPopErrorHandler();
122   }
123 %}
124 
125 %thread;
126 
127 #else
128 %inline %{
129   CPLErr PushErrorHandler( char const * pszCallbackName = NULL ) {
130     CPLErrorHandler pfnHandler = NULL;
131     if( pszCallbackName == NULL || EQUAL(pszCallbackName,"CPLQuietErrorHandler") )
132       pfnHandler = CPLQuietErrorHandler;
133     else if( EQUAL(pszCallbackName,"CPLDefaultErrorHandler") )
134       pfnHandler = CPLDefaultErrorHandler;
135     else if( EQUAL(pszCallbackName,"CPLLoggingErrorHandler") )
136       pfnHandler = CPLLoggingErrorHandler;
137 
138     if ( pfnHandler == NULL )
139       return CE_Fatal;
140 
141     CPLPushErrorHandler( pfnHandler );
142 
143     return CE_None;
144   }
145 %}
146 #endif
147 
148 #ifdef SWIGJAVA
149 %inline%{
Error(CPLErr msg_class,int err_code,const char * msg)150   void Error( CPLErr msg_class, int err_code, const char* msg ) {
151     CPLError( msg_class, err_code, "%s", msg );
152   }
153 %}
154 #else
155 %inline%{
156   void Error( CPLErr msg_class = CE_Failure, int err_code = 0, const char* msg = "error" ) {
157     CPLError( msg_class, err_code, "%s", msg );
158   }
159 %}
160 #endif
161 
162 %rename (PushErrorHandler) CPLPushErrorHandler;
163 %rename (PopErrorHandler) CPLPopErrorHandler;
164 %rename (ErrorReset) CPLErrorReset;
165 %rename (GetLastErrorNo) CPLGetLastErrorNo;
166 %rename (GetLastErrorType) CPLGetLastErrorType;
167 %rename (GetLastErrorMsg) CPLGetLastErrorMsg;
168 %rename (GetErrorCounter) CPLGetErrorCounter;
169 %rename (PushFinderLocation) CPLPushFinderLocation;
170 %rename (PopFinderLocation) CPLPopFinderLocation;
171 %rename (FinderClean) CPLFinderClean;
172 %rename (FindFile) CPLFindFile;
173 %rename (ReadDir) wrapper_VSIReadDirEx;
174 %rename (ReadDirRecursive) VSIReadDirRecursive;
175 %rename (Mkdir) VSIMkdir;
176 %rename (MkdirRecursive) VSIMkdirRecursive;
177 %rename (Rmdir) VSIRmdir;
178 %rename (RmdirRecursive) VSIRmdirRecursive;
179 %rename (Rename) VSIRename;
180 %rename (GetActualURL) VSIGetActualURL;
181 %rename (GetSignedURL) wrapper_VSIGetSignedURL;
182 %rename (GetFileSystemsPrefixes) VSIGetFileSystemsPrefixes;
183 %rename (GetFileSystemOptions) VSIGetFileSystemOptions;
184 %rename (SetConfigOption) CPLSetConfigOption;
185 %rename (GetConfigOption) wrapper_CPLGetConfigOption;
186 %rename (CPLBinaryToHex) CPLBinaryToHex;
187 %rename (CPLHexToBinary) CPLHexToBinary;
188 %rename (FileFromMemBuffer) wrapper_VSIFileFromMemBuffer;
189 %rename (Unlink) VSIUnlink;
190 %rename (HasThreadSupport) wrapper_HasThreadSupport;
191 %rename (NetworkStatsReset) VSINetworkStatsReset;
192 %rename (NetworkStatsGetAsSerializedJSON) VSINetworkStatsGetAsSerializedJSON;
193 
194 %apply Pointer NONNULL {const char *pszScope};
195 retStringAndCPLFree*
196 GOA2GetAuthorizationURL( const char *pszScope );
197 %clear (const char *pszScope);
198 
199 %apply Pointer NONNULL {const char *pszAuthToken};
200 retStringAndCPLFree*
201 GOA2GetRefreshToken( const char *pszAuthToken, const char *pszScope );
202 %clear (const char *pszAuthToken);
203 
204 %apply Pointer NONNULL {const char *pszRefreshToken};
205 retStringAndCPLFree*
206 GOA2GetAccessToken( const char *pszRefreshToken, const char *pszScope );
207 %clear (const char *pszRefreshToken);
208 
209 #if !defined(SWIGJAVA) && !defined(SWIGPYTHON)
210 void CPLPushErrorHandler( CPLErrorHandler );
211 #endif
212 
213 #if !defined(SWIGPYTHON)
214 void CPLPopErrorHandler();
215 #endif
216 
217 void CPLErrorReset();
218 
219 #ifndef SWIGJAVA
220 %feature( "kwargs" ) EscapeString;
221 #endif
222 
223 #ifdef SWIGJAVA
224 %apply (int nLen, unsigned char *pBuf ) {( int len, unsigned char *bin_string )};
225 %inline %{
EscapeString(int len,unsigned char * bin_string,int scheme)226 retStringAndCPLFree* EscapeString(int len, unsigned char *bin_string , int scheme) {
227     return CPLEscapeString((const char*)bin_string, len, scheme);
228 }
229 
EscapeString(const char * str,int scheme)230 retStringAndCPLFree* EscapeString(const char* str, int scheme) {
231     return CPLEscapeString(str, (str) ? strlen(str) : 0, scheme);
232 }
233 %}
234 %clear (int len, unsigned char *bin_string);
235 #elif defined(SWIGCSHARP)
236 %inline %{
EscapeString(int len,char * bin_string,int scheme)237 retStringAndCPLFree* EscapeString(int len, char *bin_string , int scheme) {
238     return CPLEscapeString((const char*)bin_string, len, scheme);
239 }
240 %}
241 
242 retStringAndCPLFree* EscapeString(int len, char *bin_string , int scheme=CPLES_SQL) {
243     return CPLEscapeString(bin_string, len, scheme);
244 }
245 #elif defined(SWIGPYTHON) || defined(SWIGPERL)
246 %apply (int nLen, char *pBuf ) { (int len, char *bin_string)};
247 %inline %{
248 retStringAndCPLFree* EscapeString(int len, char *bin_string , int scheme=CPLES_SQL) {
249     return CPLEscapeString(bin_string, len, scheme);
250 }
251 %}
252 %clear (int len, char *bin_string);
253 #else
254 %apply (int nLen, char *pBuf ) { (int len, char *bin_string)};
255 %inline %{
256 char* EscapeString(int len, char *bin_string , int scheme=CPLES_SQL) {
257     return CPLEscapeString(bin_string, len, scheme);
258 }
259 %}
260 %clear (int len, char *bin_string);
261 #endif
262 
263 #if defined(SWIGPYTHON) || defined(SWIGCSHARP)
264 /* We don't want errors to be cleared or thrown by this */
265 /* call */
266 %exception CPLGetLastErrorNo
267 {
268 #ifdef SWIGPYTHON
269 %#ifdef SED_HACKS
270     if( bUseExceptions ) bLocalUseExceptionsCode = FALSE;
271 %#endif
272 #endif
273     result = CPLGetLastErrorNo();
274 }
275 #endif
276 int CPLGetLastErrorNo();
277 
278 #if defined(SWIGPYTHON) || defined(SWIGCSHARP)
279 /* We don't want errors to be cleared or thrown by this */
280 /* call */
281 %exception CPLGetLastErrorType
282 {
283 #ifdef SWIGPYTHON
284 %#ifdef SED_HACKS
285     if( bUseExceptions ) bLocalUseExceptionsCode = FALSE;
286 %#endif
287 #endif
288     result = CPLGetLastErrorType();
289 }
290 int CPLGetLastErrorType();
291 #else
292 CPLErr CPLGetLastErrorType();
293 #endif
294 
295 #if defined(SWIGPYTHON) || defined(SWIGCSHARP)
296 /* We don't want errors to be cleared or thrown by this */
297 /* call */
298 %exception CPLGetLastErrorMsg
299 {
300 #ifdef SWIGPYTHON
301 %#ifdef SED_HACKS
302     if( bUseExceptions ) bLocalUseExceptionsCode = FALSE;
303 %#endif
304 #endif
305     result = (char*)CPLGetLastErrorMsg();
306 }
307 #endif
308 const char *CPLGetLastErrorMsg();
309 
310 
311 #if defined(SWIGPYTHON) || defined(SWIGCSHARP)
312 /* We don't want errors to be cleared or thrown by this */
313 /* call */
314 %exception CPLGetErrorCounter
315 {
316 #ifdef SWIGPYTHON
317 %#ifdef SED_HACKS
318     if( bUseExceptions ) bLocalUseExceptionsCode = FALSE;
319 %#endif
320 #endif
321     result = CPLGetErrorCounter();
322 }
323 #endif
324 unsigned int CPLGetErrorCounter();
325 
326 
327 int VSIGetLastErrorNo();
328 const char *VSIGetLastErrorMsg();
329 void VSIErrorReset();
330 
331 void CPLPushFinderLocation( const char * utf8_path );
332 
333 void CPLPopFinderLocation();
334 
335 void CPLFinderClean();
336 
337 const char * CPLFindFile( const char *pszClass, const char *utf8_path );
338 
339 %apply (char **CSL) {char **};
340 %inline {
341 char **wrapper_VSIReadDirEx( const char * utf8_path, int nMaxFiles = 0 )
342 {
343     return VSIReadDirEx(utf8_path, nMaxFiles);
344 }
345 }
346 %clear char **;
347 
348 %apply (char **CSL) {char **};
349 char **VSIReadDirRecursive( const char * utf8_path );
350 %clear char **;
351 
352 #ifdef SWIGPYTHON
353 %rename (OpenDir) wrapper_VSIOpenDir;
354 %inline {
355 VSIDIR* wrapper_VSIOpenDir( const char * utf8_path,
356                             int nRecurseDepth = -1,
357                             char** options = NULL )
358 {
359     return VSIOpenDir(utf8_path, nRecurseDepth, options);
360 }
361 }
362 
363 %{
364 typedef struct
365 {
366     char*        name;
367     int          mode;
368     GIntBig      size;
369     GIntBig      mtime;
370     bool         modeKnown;
371     bool         sizeKnown;
372     bool         mtimeKnown;
373     char**       extra;
374 } DirEntry;
375 %}
376 
377 struct DirEntry
378 {
379 %immutable;
380     char*        name;
381     int          mode;
382     GIntBig      size;
383     GIntBig      mtime;
384     bool         modeKnown;
385     bool         sizeKnown;
386     bool         mtimeKnown;
387 
388 %apply (char **dict) {char **};
389     char**       extra;
390 %clear char **;
391 %mutable;
392 
393 %extend {
DirEntryDirEntry394   DirEntry( const DirEntry *entryIn ) {
395     DirEntry *self = (DirEntry*) CPLMalloc( sizeof( DirEntry ) );
396     self->name = CPLStrdup(entryIn->name);
397     self->mode = entryIn->mode;
398     self->size = entryIn->size;
399     self->mtime = entryIn->mtime;
400     self->modeKnown = entryIn->modeKnown;
401     self->sizeKnown = entryIn->sizeKnown;
402     self->mtimeKnown = entryIn->mtimeKnown;
403     self->extra = CSLDuplicate(entryIn->extra);
404     return self;
405   }
406 
~DirEntryDirEntry407   ~DirEntry() {
408     CPLFree(self->name);
409     CSLDestroy(self->extra);
410     CPLFree(self);
411   }
412 
IsDirectoryDirEntry413   bool IsDirectory()
414   {
415      return (self->mode & S_IFDIR) != 0;
416   }
417 
418 } /* extend */
419 } /* DirEntry */ ;
420 
421 %rename (GetNextDirEntry) wrapper_VSIGetNextDirEntry;
422 %newobject wrapper_VSIGetNextDirEntry;
423 %apply Pointer NONNULL {VSIDIR* dir};
424 %inline {
wrapper_VSIGetNextDirEntry(VSIDIR * dir)425 DirEntry* wrapper_VSIGetNextDirEntry(VSIDIR* dir)
426 {
427     const VSIDIREntry* vsiEntry = VSIGetNextDirEntry(dir);
428     if( vsiEntry == nullptr )
429     {
430         return nullptr;
431     }
432     DirEntry* entry = (DirEntry*) CPLMalloc( sizeof( DirEntry ) );
433     entry->name = CPLStrdup(vsiEntry->pszName);
434     entry->mode = vsiEntry->nMode;
435     entry->size = vsiEntry->nSize;
436     entry->mtime = vsiEntry->nMTime;
437     entry->modeKnown = vsiEntry->bModeKnown == TRUE;
438     entry->sizeKnown = vsiEntry->bSizeKnown == TRUE;
439     entry->mtimeKnown = vsiEntry->bMTimeKnown == TRUE;
440     entry->extra = CSLDuplicate(vsiEntry->papszExtra);
441     return entry;
442 }
443 }
444 
445 %rename (CloseDir) VSICloseDir;
446 void VSICloseDir(VSIDIR* dir);
447 
448 #endif
449 
450 %apply Pointer NONNULL {const char * pszKey};
451 void CPLSetConfigOption( const char * pszKey, const char * pszValue );
452 
453 %inline {
454 const char *wrapper_CPLGetConfigOption( const char * pszKey, const char * pszDefault = NULL )
455 {
456     return CPLGetConfigOption( pszKey, pszDefault );
457 }
458 }
459 %clear const char * pszKey;
460 
461 /* Provide hooks to hex encoding methods */
462 #if defined(SWIGJAVA) || defined(SWIGPERL)
463 %apply (int nLen, unsigned char *pBuf ) {( int nBytes, const GByte *pabyData )};
464 retStringAndCPLFree* CPLBinaryToHex( int nBytes, const GByte *pabyData );
465 %clear ( int nBytes, const GByte *pabyData );
466 #elif defined(SWIGCSHARP)
467 retStringAndCPLFree* CPLBinaryToHex( int nBytes, const GByte *pabyData );
468 #elif defined(SWIGPYTHON)
469 %apply (int nLen, char *pBuf) {( int nBytes, const GByte *pabyData )};
470 retStringAndCPLFree* CPLBinaryToHex( int nBytes, const GByte *pabyData );
471 %clear ( int nBytes, const GByte *pabyData );
472 #else
473 /* FIXME : wrong typemap. The string should be freed */
474 char * CPLBinaryToHex( int nBytes, const GByte *pabyData );
475 #endif
476 
477 #ifdef SWIGJAVA
478 %apply (GByte* outBytes) {GByte*};
479 #endif
480 GByte *CPLHexToBinary( const char *pszHex, int *pnBytes );
481 #ifdef SWIGJAVA
482 %clear GByte*;
483 #endif
484 
485 %apply Pointer NONNULL {const char * pszFilename};
486 /* Added in GDAL 1.7.0 */
487 
488 #if defined(SWIGPYTHON)
489 
490 %apply (GIntBig nLen, char *pBuf) {( GIntBig nBytes, const char *pabyData )};
491 %inline {
wrapper_VSIFileFromMemBuffer(const char * utf8_path,GIntBig nBytes,const char * pabyData)492 void wrapper_VSIFileFromMemBuffer( const char* utf8_path, GIntBig nBytes, const char *pabyData)
493 {
494     const size_t nSize = static_cast<size_t>(nBytes);
495     void* pabyDataDup = VSIMalloc(nSize);
496     if (pabyDataDup == NULL)
497             return;
498     memcpy(pabyDataDup, pabyData, nSize);
499     VSIFCloseL(VSIFileFromMemBuffer(utf8_path, (GByte*) pabyDataDup, nSize, TRUE));
500 }
501 }
502 %clear ( GIntBig nBytes, const GByte *pabyData );
503 #else
504 #if defined(SWIGJAVA)
505 %apply (int nLen, unsigned char *pBuf ) {( int nBytes, const GByte *pabyData )};
506 #endif
507 %inline {
wrapper_VSIFileFromMemBuffer(const char * utf8_path,int nBytes,const GByte * pabyData)508 void wrapper_VSIFileFromMemBuffer( const char* utf8_path, int nBytes, const GByte *pabyData)
509 {
510     GByte* pabyDataDup = (GByte*)VSIMalloc(nBytes);
511     if (pabyDataDup == NULL)
512             return;
513     memcpy(pabyDataDup, pabyData, nBytes);
514     VSIFCloseL(VSIFileFromMemBuffer(utf8_path, (GByte*) pabyDataDup, nBytes, TRUE));
515 }
516 
517 }
518 #if defined(SWIGJAVA)
519 %clear ( int nBytes, const GByte *pabyData );
520 #endif
521 #endif
522 
523 /* Added in GDAL 1.7.0 */
524 VSI_RETVAL VSIUnlink(const char * utf8_path );
525 
526 %rename (UnlinkBatch) wrapper_VSIUnlinkBatch;
527 %apply (char **options) {char ** files};
528 %inline {
wrapper_VSIUnlinkBatch(char ** files)529 bool wrapper_VSIUnlinkBatch(char** files)
530 {
531     int* success = VSIUnlinkBatch(files);
532     if( !success )
533         return false;
534     int bRet = true;
535     for( int i = 0; files && files[i]; i++ )
536     {
537         if( !success[i] ) {
538             bRet = false;
539             break;
540         }
541     }
542     VSIFree(success);
543     return bRet;
544 }
545 }
546 %clear (char **files);
547 
548 /* Added in GDAL 1.7.0 */
549 /* Thread support is necessary for binding languages with threaded GC */
550 /* even if the user doesn't explicitly use threads */
551 %inline {
wrapper_HasThreadSupport()552 int wrapper_HasThreadSupport()
553 {
554     return strcmp(CPLGetThreadingModel(), "stub") != 0;
555 }
556 }
557 
558 /* Added for GDAL 1.8 */
559 VSI_RETVAL VSIMkdir(const char *utf8_path, int mode );
560 VSI_RETVAL VSIRmdir(const char *utf8_path );
561 
562 /* Added for GDAL 2.3 */
563 VSI_RETVAL VSIMkdirRecursive(const char *utf8_path, int mode );
564 VSI_RETVAL VSIRmdirRecursive(const char *utf8_path );
565 
566 %apply (const char* utf8_path) {(const char* pszOld)};
567 %apply (const char* utf8_path) {(const char* pszNew)};
568 VSI_RETVAL VSIRename(const char * pszOld, const char *pszNew );
569 %clear (const char* pszOld);
570 %clear (const char* pszNew);
571 
572 #if defined(SWIGPYTHON)
573 %rename (Sync) wrapper_VSISync;
574 
575 %apply (const char* utf8_path) {(const char* pszSource)};
576 %apply (const char* utf8_path) {(const char* pszTarget)};
577 %feature( "kwargs" ) wrapper_VSISync;
578 
579 %inline {
580 bool wrapper_VSISync(const char* pszSource,
581                      const char* pszTarget,
582                      char** options = NULL,
583                      GDALProgressFunc callback=NULL,
584                      void* callback_data=NULL)
585 {
586     return VSISync( pszSource, pszTarget, options, callback, callback_data, nullptr );
587 }
588 }
589 
590 %clear (const char* pszSource);
591 %clear (const char* pszTarget);
592 
593 #endif
594 
595 const char* VSIGetActualURL(const char * utf8_path);
596 
597 %inline {
598 retStringAndCPLFree* wrapper_VSIGetSignedURL(const char * utf8_path, char** options = NULL )
599 {
600     return VSIGetSignedURL( utf8_path, options );
601 }
602 }
603 
604 %apply (char **CSL) {char **};
605 char** VSIGetFileSystemsPrefixes();
606 %clear char **;
607 
608 const char* VSIGetFileSystemOptions(const char * utf8_path);
609 
610 
611 /* Added for GDAL 1.8
612 
613    We do not bother renaming the VSI*L api as this wrapping is not
614    considered "official", or available for use by application code.
615    It is just for some testing stuff.
616 */
617 
618 #if !defined(SWIGJAVA)
619 
620 #if !defined(SWIGCSHARP)
621 class VSILFILE
622 {
623     private:
624         VSILFILE();
625         ~VSILFILE();
626 };
627 #endif
628 
629 #if defined(SWIGPERL)
630 VSI_RETVAL VSIStatL( const char * utf8_path, VSIStatBufL *psStatBuf );
631 
632 #elif defined(SWIGPYTHON)
633 
634 %{
635 typedef struct
636 {
637   int     mode;
638   GIntBig size;
639   GIntBig mtime;
640 } StatBuf;
641 %}
642 
643 #define VSI_STAT_EXISTS_FLAG    0x1
644 #define VSI_STAT_NATURE_FLAG    0x2
645 #define VSI_STAT_SIZE_FLAG      0x4
646 
647 struct StatBuf
648 {
649 %immutable;
650   int         mode;
651   GIntBig     size;
652   GIntBig     mtime;
653 %mutable;
654 
655 %extend {
StatBufStatBuf656   StatBuf( StatBuf *psStatBuf ) {
657     StatBuf *self = (StatBuf*) CPLMalloc( sizeof( StatBuf ) );
658     self->mode = psStatBuf->mode;
659     self->size = psStatBuf->size;
660     self->mtime = psStatBuf->mtime;
661     return self;
662   }
663 
~StatBufStatBuf664   ~StatBuf() {
665     CPLFree(self);
666   }
667 
IsDirectoryStatBuf668   int IsDirectory()
669   {
670      return (self->mode & S_IFDIR) != 0;
671   }
672 
673 } /* extend */
674 } /* StatBuf */ ;
675 
676 %rename (VSIStatL) wrapper_VSIStatL;
677 %inline {
678 int wrapper_VSIStatL( const char * utf8_path, StatBuf *psStatBufOut, int nFlags = 0 )
679 {
680     VSIStatBufL sStat;
681     memset(&sStat, 0, sizeof(sStat));
682     memset(psStatBufOut, 0, sizeof(StatBuf));
683     int nRet = VSIStatExL(utf8_path, &sStat, nFlags);
684     psStatBufOut->mode = sStat.st_mode;
685     psStatBufOut->size = (GIntBig)sStat.st_size;
686     psStatBufOut->mtime = (GIntBig)sStat.st_mtime;
687     return nRet;
688 }
689 }
690 
691 #endif
692 
693 %rename (GetFileMetadata) VSIGetFileMetadata;
694 %apply (char **dict) { char ** };
695 char** VSIGetFileMetadata( const char *utf8_path, const char* domain,
696                            char** options = NULL );
697 %clear char **;
698 
699 %rename (SetFileMetadata) VSISetFileMetadata;
700 %apply (char **dict) { char ** metadata };
701 bool VSISetFileMetadata( const char * utf8_path,
702                          char** metadata,
703                          const char* domain,
704                          char** options = NULL );
705 %clear char **;
706 
707 %apply Pointer NONNULL {VSILFILE* fp};
708 
709 %rename (VSIFOpenL) wrapper_VSIFOpenL;
710 %inline %{
wrapper_VSIFOpenL(const char * utf8_path,const char * pszMode)711 VSILFILE   *wrapper_VSIFOpenL( const char *utf8_path, const char *pszMode )
712 {
713     if (!pszMode) /* would lead to segfault */
714         pszMode = "r";
715     return VSIFOpenL( utf8_path, pszMode );
716 }
717 %}
718 
719 %rename (VSIFOpenExL) wrapper_VSIFOpenExL;
720 %apply (char **dict) { char ** };
721 %inline %{
722 VSILFILE   *wrapper_VSIFOpenExL( const char *utf8_path, const char *pszMode, int bSetError = FALSE, char** options = NULL )
723 {
724     if (!pszMode) /* would lead to segfault */
725         pszMode = "r";
726     return VSIFOpenEx2L( utf8_path, pszMode, bSetError, options );
727 }
728 %}
729 %clear char **;
730 
731 int VSIFEofL( VSILFILE* fp );
732 int VSIFFlushL( VSILFILE* fp );
733 
734 VSI_RETVAL VSIFCloseL( VSILFILE* fp );
735 
736 #if defined(SWIGPYTHON)
737 int     VSIFSeekL( VSILFILE* fp, GIntBig offset, int whence);
738 GIntBig    VSIFTellL( VSILFILE* fp );
739 int     VSIFTruncateL( VSILFILE* fp, GIntBig length );
740 
741 int     VSISupportsSparseFiles( const char* utf8_path );
742 
743 #define VSI_RANGE_STATUS_UNKNOWN    0
744 #define VSI_RANGE_STATUS_DATA       1
745 #define VSI_RANGE_STATUS_HOLE       2
746 
747 int     VSIFGetRangeStatusL( VSILFILE* fp, GIntBig offset, GIntBig length );
748 #else
749 VSI_RETVAL VSIFSeekL( VSILFILE* fp, long offset, int whence);
750 long    VSIFTellL( VSILFILE* fp );
751 VSI_RETVAL VSIFTruncateL( VSILFILE* fp, long length );
752 #endif
753 
754 #if defined(SWIGPYTHON)
755 %rename (VSIFWriteL) wrapper_VSIFWriteL;
756 %inline {
wrapper_VSIFWriteL(int nLen,char * pBuf,int size,int memb,VSILFILE * fp)757 int wrapper_VSIFWriteL( int nLen, char *pBuf, int size, int memb, VSILFILE* fp)
758 {
759     if (nLen < static_cast<GIntBig>(size) * memb)
760     {
761         CPLError(CE_Failure, CPLE_AppDefined, "Inconsistent buffer size with 'size' and 'memb' values");
762         return 0;
763     }
764     return static_cast<int>(VSIFWriteL(pBuf, size, memb, fp));
765 }
766 }
767 #elif defined(SWIGPERL)
768 size_t VSIFWriteL(const void *pBuffer, size_t nSize, size_t nCount, VSILFILE *fp);
769 #else
770 int     VSIFWriteL( const char *, int, int, VSILFILE *fp );
771 #endif
772 
773 #if defined(SWIGPERL)
774 size_t VSIFReadL(void *pBuffer, size_t nSize, size_t nCount, VSILFILE *fp);
775 #endif
776 /* VSIFReadL() handled specially in python/gdal_python.i */
777 
778 #if defined(SWIGPERL)
779 void VSIStdoutSetRedirection( VSIWriteFunction pFct, FILE* stream );
780 %inline {
VSIStdoutUnsetRedirection()781 void VSIStdoutUnsetRedirection()
782 {
783     VSIStdoutSetRedirection( fwrite, stdout );
784 }
785 }
786 #endif
787 
788 void VSICurlClearCache();
789 void VSICurlPartialClearCache( const char* utf8_path );
790 
791 void VSINetworkStatsReset();
792 retStringAndCPLFree* VSINetworkStatsGetAsSerializedJSON( char** options = NULL );
793 
794 #endif /* !defined(SWIGJAVA) */
795 
796 %apply (char **CSL) {char **};
797 %rename (ParseCommandLine) CSLParseCommandLine;
798 char **CSLParseCommandLine( const char * utf8_path );
799 %clear char **;
800