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