1 /* 2 * utility functions 3 * 4 * src/pl/plpython/plpy_util.c 5 */ 6 7 #include "postgres.h" 8 9 #include "mb/pg_wchar.h" 10 #include "plpy_elog.h" 11 #include "plpy_util.h" 12 #include "plpython.h" 13 #include "utils/memutils.h" 14 15 /* 16 * Convert a Python unicode object to a Python string/bytes object in 17 * PostgreSQL server encoding. Reference ownership is passed to the 18 * caller. 19 */ 20 PyObject * 21 PLyUnicode_Bytes(PyObject *unicode) 22 { 23 PyObject *bytes, 24 *rv; 25 char *utf8string, 26 *encoded; 27 28 /* First encode the Python unicode object with UTF-8. */ 29 bytes = PyUnicode_AsUTF8String(unicode); 30 if (bytes == NULL) 31 PLy_elog(ERROR, "could not convert Python Unicode object to bytes"); 32 33 utf8string = PyBytes_AsString(bytes); 34 if (utf8string == NULL) 35 { 36 Py_DECREF(bytes); 37 PLy_elog(ERROR, "could not extract bytes from encoded string"); 38 } 39 40 /* 41 * Then convert to server encoding if necessary. 42 * 43 * PyUnicode_AsEncodedString could be used to encode the object directly 44 * in the server encoding, but Python doesn't support all the encodings 45 * that PostgreSQL does (EUC_TW and MULE_INTERNAL). UTF-8 is used as an 46 * intermediary in PLyUnicode_FromString as well. 47 */ 48 if (GetDatabaseEncoding() != PG_UTF8) 49 { 50 PG_TRY(); 51 { 52 encoded = pg_any_to_server(utf8string, 53 strlen(utf8string), 54 PG_UTF8); 55 } 56 PG_CATCH(); 57 { 58 Py_DECREF(bytes); 59 PG_RE_THROW(); 60 } 61 PG_END_TRY(); 62 } 63 else 64 encoded = utf8string; 65 66 /* finally, build a bytes object in the server encoding */ 67 rv = PyBytes_FromStringAndSize(encoded, strlen(encoded)); 68 69 /* if pg_any_to_server allocated memory, free it now */ 70 if (utf8string != encoded) 71 pfree(encoded); 72 73 Py_DECREF(bytes); 74 return rv; 75 } 76 77 /* 78 * Convert a Python unicode object to a C string in PostgreSQL server 79 * encoding. No Python object reference is passed out of this 80 * function. The result is palloc'ed. 81 * 82 * Note that this function is disguised as PyString_AsString() when 83 * using Python 3. That function returns a pointer into the internal 84 * memory of the argument, which isn't exactly the interface of this 85 * function. But in either case you get a rather short-lived 86 * reference that you ought to better leave alone. 87 */ 88 char * 89 PLyUnicode_AsString(PyObject *unicode) 90 { 91 PyObject *o = PLyUnicode_Bytes(unicode); 92 char *rv = pstrdup(PyBytes_AsString(o)); 93 94 Py_XDECREF(o); 95 return rv; 96 } 97 98 #if PY_MAJOR_VERSION >= 3 99 /* 100 * Convert a C string in the PostgreSQL server encoding to a Python 101 * unicode object. Reference ownership is passed to the caller. 102 */ 103 PyObject * 104 PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size) 105 { 106 char *utf8string; 107 PyObject *o; 108 109 utf8string = pg_server_to_any(s, size, PG_UTF8); 110 111 if (utf8string == s) 112 { 113 o = PyUnicode_FromStringAndSize(s, size); 114 } 115 else 116 { 117 o = PyUnicode_FromString(utf8string); 118 pfree(utf8string); 119 } 120 121 return o; 122 } 123 124 PyObject * 125 PLyUnicode_FromString(const char *s) 126 { 127 return PLyUnicode_FromStringAndSize(s, strlen(s)); 128 } 129 130 #endif /* PY_MAJOR_VERSION >= 3 */ 131