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 *
19 2419 : 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. */
27 2419 : bytes = PyUnicode_AsUTF8String(unicode);
28 2419 : if (bytes == NULL)
29 0 : PLy_elog(ERROR, "could not convert Python Unicode object to bytes");
30 :
31 2419 : utf8string = PyBytes_AsString(bytes);
32 2419 : if (utf8string == NULL)
33 : {
34 : Py_DECREF(bytes);
35 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 and MULE_INTERNAL). UTF-8 is used as an
44 : * intermediary in PLyUnicode_FromString as well.
45 : */
46 2419 : if (GetDatabaseEncoding() != PG_UTF8)
47 : {
48 0 : PG_TRY();
49 : {
50 0 : encoded = pg_any_to_server(utf8string,
51 0 : strlen(utf8string),
52 : PG_UTF8);
53 : }
54 0 : PG_CATCH();
55 : {
56 : Py_DECREF(bytes);
57 0 : PG_RE_THROW();
58 : }
59 0 : PG_END_TRY();
60 : }
61 : else
62 2419 : encoded = utf8string;
63 :
64 : /* finally, build a bytes object in the server encoding */
65 2419 : rv = PyBytes_FromStringAndSize(encoded, strlen(encoded));
66 :
67 : /* if pg_any_to_server allocated memory, free it now */
68 2419 : if (utf8string != encoded)
69 0 : pfree(encoded);
70 :
71 : Py_DECREF(bytes);
72 2419 : 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 835 : PLyUnicode_AsString(PyObject *unicode)
82 : {
83 835 : PyObject *o = PLyUnicode_Bytes(unicode);
84 835 : char *rv = pstrdup(PyBytes_AsString(o));
85 :
86 835 : Py_XDECREF(o);
87 835 : 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 *
95 6755 : PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size)
96 : {
97 : char *utf8string;
98 : PyObject *o;
99 :
100 6755 : utf8string = pg_server_to_any(s, size, PG_UTF8);
101 :
102 6755 : if (utf8string == s)
103 : {
104 6755 : o = PyUnicode_FromStringAndSize(s, size);
105 : }
106 : else
107 : {
108 0 : o = PyUnicode_FromString(utf8string);
109 0 : pfree(utf8string);
110 : }
111 :
112 6755 : return o;
113 : }
114 :
115 : PyObject *
116 6708 : PLyUnicode_FromString(const char *s)
117 : {
118 6708 : return PLyUnicode_FromStringAndSize(s, strlen(s));
119 : }
|