Age Owner TLA Line data Source code
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 *
4130 peter_e 21 CBC 2389 : 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. */
3898 heikki.linnakangas 29 2389 : bytes = PyUnicode_AsUTF8String(unicode);
30 2389 : if (bytes == NULL)
3898 heikki.linnakangas 31 UBC 0 : PLy_elog(ERROR, "could not convert Python Unicode object to bytes");
32 :
3898 heikki.linnakangas 33 CBC 2389 : utf8string = PyBytes_AsString(bytes);
3602 bruce 34 2389 : if (utf8string == NULL)
35 : {
3898 heikki.linnakangas 36 UBC 0 : Py_DECREF(bytes);
37 0 : 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 : */
3898 heikki.linnakangas 48 CBC 2389 : if (GetDatabaseEncoding() != PG_UTF8)
49 : {
3898 heikki.linnakangas 50 UBC 0 : PG_TRY();
51 : {
3332 tgl 52 0 : encoded = pg_any_to_server(utf8string,
53 0 : strlen(utf8string),
54 : PG_UTF8);
55 : }
3898 heikki.linnakangas 56 0 : PG_CATCH();
57 : {
58 0 : Py_DECREF(bytes);
59 0 : PG_RE_THROW();
60 : }
61 0 : PG_END_TRY();
62 : }
63 : else
3898 heikki.linnakangas 64 CBC 2389 : encoded = utf8string;
65 :
66 : /* finally, build a bytes object in the server encoding */
67 2389 : rv = PyBytes_FromStringAndSize(encoded, strlen(encoded));
68 :
69 : /* if pg_any_to_server allocated memory, free it now */
70 2389 : if (utf8string != encoded)
3898 heikki.linnakangas 71 UBC 0 : pfree(encoded);
72 :
3898 heikki.linnakangas 73 CBC 2389 : Py_DECREF(bytes);
4130 peter_e 74 2389 : 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 : char *
83 819 : PLyUnicode_AsString(PyObject *unicode)
84 : {
85 819 : PyObject *o = PLyUnicode_Bytes(unicode);
86 819 : char *rv = pstrdup(PyBytes_AsString(o));
87 :
88 819 : Py_XDECREF(o);
89 819 : return rv;
90 : }
91 :
92 : /*
93 : * Convert a C string in the PostgreSQL server encoding to a Python
94 : * unicode object. Reference ownership is passed to the caller.
95 : */
96 : PyObject *
2905 97 6663 : PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size)
98 : {
99 : char *utf8string;
100 : PyObject *o;
101 :
102 6663 : utf8string = pg_server_to_any(s, size, PG_UTF8);
103 :
104 6663 : if (utf8string == s)
105 : {
106 6663 : o = PyUnicode_FromStringAndSize(s, size);
107 : }
108 : else
109 : {
2905 peter_e 110 UBC 0 : o = PyUnicode_FromString(utf8string);
4130 111 0 : pfree(utf8string);
112 : }
113 :
4130 peter_e 114 CBC 6663 : return o;
115 : }
116 :
117 : PyObject *
2905 118 6616 : PLyUnicode_FromString(const char *s)
119 : {
120 6616 : return PLyUnicode_FromStringAndSize(s, strlen(s));
121 : }
|