Age Owner Branch data 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 : :
13 : : /*
14 : : * Convert a Python unicode object to a Python string/bytes object in
15 : : * PostgreSQL server encoding. Reference ownership is passed to the
16 : : * caller.
17 : : */
18 : : PyObject *
5308 peter_e@gmx.net 19 :CBC 2488 : PLyUnicode_Bytes(PyObject *unicode)
20 : : {
21 : : PyObject *bytes,
22 : : *rv;
23 : : char *utf8string,
24 : : *encoded;
25 : :
26 : : /* First encode the Python unicode object with UTF-8. */
5076 heikki.linnakangas@i 27 : 2488 : bytes = PyUnicode_AsUTF8String(unicode);
28 [ - + ]: 2488 : if (bytes == NULL)
5076 heikki.linnakangas@i 29 :UBC 0 : PLy_elog(ERROR, "could not convert Python Unicode object to bytes");
30 : :
5076 heikki.linnakangas@i 31 :CBC 2488 : utf8string = PyBytes_AsString(bytes);
4780 bruce@momjian.us 32 [ - + ]: 2488 : if (utf8string == NULL)
33 : : {
34 : : Py_DECREF(bytes);
5076 heikki.linnakangas@i 35 :UBC 0 : PLy_elog(ERROR, "could not extract bytes from encoded string");
36 : : }
37 : :
38 : : /*
39 : : * Then convert to server encoding if necessary.
40 : : *
41 : : * PyUnicode_AsEncodedString could be used to encode the object directly
42 : : * in the server encoding, but Python doesn't support all the encodings
43 : : * that PostgreSQL does (EUC_TW). UTF-8 is used as an intermediary in
44 : : * PLyUnicode_FromString as well.
45 : : */
5076 heikki.linnakangas@i 46 [ - + ]:CBC 2488 : if (GetDatabaseEncoding() != PG_UTF8)
47 : : {
5076 heikki.linnakangas@i 48 [ # # ]:UBC 0 : PG_TRY();
49 : : {
4510 tgl@sss.pgh.pa.us 50 : 0 : encoded = pg_any_to_server(utf8string,
51 : 0 : strlen(utf8string),
52 : : PG_UTF8);
53 : : }
5076 heikki.linnakangas@i 54 : 0 : PG_CATCH();
55 : : {
56 : : Py_DECREF(bytes);
57 : 0 : PG_RE_THROW();
58 : : }
59 [ # # ]: 0 : PG_END_TRY();
60 : : }
61 : : else
5076 heikki.linnakangas@i 62 :CBC 2488 : encoded = utf8string;
63 : :
64 : : /* finally, build a bytes object in the server encoding */
65 : 2488 : rv = PyBytes_FromStringAndSize(encoded, strlen(encoded));
66 : :
67 : : /* if pg_any_to_server allocated memory, free it now */
68 [ - + ]: 2488 : if (utf8string != encoded)
5076 heikki.linnakangas@i 69 :UBC 0 : pfree(encoded);
70 : :
71 : : Py_DECREF(bytes);
5308 peter_e@gmx.net 72 :CBC 2488 : return rv;
73 : : }
74 : :
75 : : /*
76 : : * Convert a Python unicode object to a C string in PostgreSQL server
77 : : * encoding. No Python object reference is passed out of this
78 : : * function. The result is palloc'ed.
79 : : */
80 : : char *
81 : 876 : PLyUnicode_AsString(PyObject *unicode)
82 : : {
83 : 876 : PyObject *o = PLyUnicode_Bytes(unicode);
84 : 876 : char *rv = pstrdup(PyBytes_AsString(o));
85 : :
86 : 876 : Py_XDECREF(o);
87 : 876 : return rv;
88 : : }
89 : :
90 : : /*
91 : : * Convert a C string in the PostgreSQL server encoding to a Python
92 : : * unicode object. Reference ownership is passed to the caller.
93 : : */
94 : : PyObject *
4083 95 : 6779 : PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size)
96 : : {
97 : : char *utf8string;
98 : : PyObject *o;
99 : :
100 : 6779 : utf8string = pg_server_to_any(s, size, PG_UTF8);
101 : :
102 [ + - ]: 6779 : if (utf8string == s)
103 : : {
104 : 6779 : o = PyUnicode_FromStringAndSize(s, size);
105 : : }
106 : : else
107 : : {
4083 peter_e@gmx.net 108 :UBC 0 : o = PyUnicode_FromString(utf8string);
5308 109 : 0 : pfree(utf8string);
110 : : }
111 : :
5308 peter_e@gmx.net 112 :CBC 6779 : return o;
113 : : }
114 : :
115 : : PyObject *
4083 116 : 6732 : PLyUnicode_FromString(const char *s)
117 : : {
118 : 6732 : return PLyUnicode_FromStringAndSize(s, strlen(s));
119 : : }
|