1 /******************************************************************************
2 * $Id: python_strings.i d735c61288062ffcfdcc10d5b37e27443ffaaed7 2021-08-24 11:32:17 +0200 Even Rouault $
3 *
4 * Name: python_strings.i
5 * Project: GDAL Python Interface
6 * Author: Even Rouault, <even dot rouault at spatialys.com>
7 *
8 ******************************************************************************
9 * Copyright (c) 2009, Even Rouault
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 %{
31
32 /* Return a PyObject* from a NULL terminated C String */
33 static PyObject* GDALPythonObjectFromCStr(const char *pszStr) CPL_UNUSED;
GDALPythonObjectFromCStr(const char * pszStr)34 static PyObject* GDALPythonObjectFromCStr(const char *pszStr)
35 {
36 const unsigned char* pszIter = (const unsigned char*) pszStr;
37 while(*pszIter != 0)
38 {
39 if (*pszIter > 127)
40 {
41 PyObject* pyObj = PyUnicode_DecodeUTF8(pszStr, strlen(pszStr), "strict");
42 if (pyObj != NULL && !PyErr_Occurred())
43 return pyObj;
44 PyErr_Clear();
45 return PyBytes_FromString(pszStr);
46 }
47 pszIter ++;
48 }
49 return PyUnicode_FromString(pszStr);
50 }
51
52 /* Return a NULL terminated c String from a PyObject */
53 /* Result must be freed with GDALPythonFreeCStr */
54 static char* GDALPythonObjectToCStr(PyObject* pyObject, int* pbToFree) CPL_UNUSED;
GDALPythonObjectToCStr(PyObject * pyObject,int * pbToFree)55 static char* GDALPythonObjectToCStr(PyObject* pyObject, int* pbToFree)
56 {
57 *pbToFree = 0;
58 if (PyUnicode_Check(pyObject))
59 {
60 char *pszStr;
61 char *pszNewStr;
62 Py_ssize_t nLen;
63 PyObject* pyUTF8Str = PyUnicode_AsUTF8String(pyObject);
64 if( pyUTF8Str == NULL )
65 return NULL;
66 PyBytes_AsStringAndSize(pyUTF8Str, &pszStr, &nLen);
67 pszNewStr = (char *) malloc(nLen+1);
68 if( pszNewStr == NULL )
69 {
70 CPLError(CE_Failure, CPLE_OutOfMemory, "Failed to allocate %llu bytes",
71 (unsigned long long)(nLen + 1));
72 Py_XDECREF(pyUTF8Str);
73 return NULL;
74 }
75 memcpy(pszNewStr, pszStr, nLen+1);
76 Py_XDECREF(pyUTF8Str);
77 *pbToFree = 1;
78 return pszNewStr;
79 }
80 else if( PyBytes_Check(pyObject) )
81 {
82 char* ret = PyBytes_AsString(pyObject);
83
84 // Check if there are \0 bytes inside the string
85 const Py_ssize_t size = PyBytes_Size(pyObject);
86 for( Py_ssize_t i = 0; i < size; i++ )
87 {
88 if( ret[i] == 0 )
89 {
90 CPLError(CE_Failure, CPLE_AppDefined,
91 "bytes object cast as string contains a zero-byte.");
92 return NULL;
93 }
94 }
95
96 return ret;
97 }
98 else
99 {
100 CPLError(CE_Failure, CPLE_AppDefined,
101 "Passed object is neither of type string nor bytes");
102 return NULL;
103 }
104 }
105
106 static void GDALPythonFreeCStr(void* ptr, int bToFree) CPL_UNUSED;
GDALPythonFreeCStr(void * ptr,int bToFree)107 static void GDALPythonFreeCStr(void* ptr, int bToFree)
108 {
109 if (bToFree)
110 free(ptr);
111 }
112
113 %}
114