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 : : #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 *
4501 peter_e@gmx.net 21 :CBC 2401 : 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. */
4269 heikki.linnakangas@i 29 : 2401 : bytes = PyUnicode_AsUTF8String(unicode);
30 [ - + ]: 2401 : if (bytes == NULL)
4269 heikki.linnakangas@i 31 :UBC 0 : PLy_elog(ERROR, "could not convert Python Unicode object to bytes");
32 : :
4269 heikki.linnakangas@i 33 :CBC 2401 : utf8string = PyBytes_AsString(bytes);
3973 bruce@momjian.us 34 [ - + ]: 2401 : if (utf8string == NULL)
35 : : {
4269 heikki.linnakangas@i 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 : : */
4269 heikki.linnakangas@i 48 [ - + ]:CBC 2401 : if (GetDatabaseEncoding() != PG_UTF8)
49 : : {
4269 heikki.linnakangas@i 50 [ # # ]:UBC 0 : PG_TRY();
51 : : {
3703 tgl@sss.pgh.pa.us 52 : 0 : encoded = pg_any_to_server(utf8string,
53 : 0 : strlen(utf8string),
54 : : PG_UTF8);
55 : : }
4269 heikki.linnakangas@i 56 : 0 : PG_CATCH();
57 : : {
58 : 0 : Py_DECREF(bytes);
59 : 0 : PG_RE_THROW();
60 : : }
61 [ # # ]: 0 : PG_END_TRY();
62 : : }
63 : : else
4269 heikki.linnakangas@i 64 :CBC 2401 : encoded = utf8string;
65 : :
66 : : /* finally, build a bytes object in the server encoding */
67 : 2401 : rv = PyBytes_FromStringAndSize(encoded, strlen(encoded));
68 : :
69 : : /* if pg_any_to_server allocated memory, free it now */
70 [ - + ]: 2401 : if (utf8string != encoded)
4269 heikki.linnakangas@i 71 :UBC 0 : pfree(encoded);
72 : :
4269 heikki.linnakangas@i 73 :CBC 2401 : Py_DECREF(bytes);
4501 peter_e@gmx.net 74 : 2401 : 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 : 822 : PLyUnicode_AsString(PyObject *unicode)
84 : : {
85 : 822 : PyObject *o = PLyUnicode_Bytes(unicode);
86 : 822 : char *rv = pstrdup(PyBytes_AsString(o));
87 : :
88 : 822 : Py_XDECREF(o);
89 : 822 : 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 *
3276 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 : : {
3276 peter_e@gmx.net 110 :UBC 0 : o = PyUnicode_FromString(utf8string);
4501 111 : 0 : pfree(utf8string);
112 : : }
113 : :
4501 peter_e@gmx.net 114 :CBC 6663 : return o;
115 : : }
116 : :
117 : : PyObject *
3276 118 : 6616 : PLyUnicode_FromString(const char *s)
119 : : {
120 : 6616 : return PLyUnicode_FromStringAndSize(s, strlen(s));
121 : : }
|