/* Convert a PostgreSQL encoding to a Python codec. * * Set 'codec' to a new copy of the codec name allocated on the Python heap. * Return 0 in case of success, else -1 and set an exception. * * 'enc' should be already normalized (uppercase, no - or _). */ RAISES_NEG static int conn_encoding_to_codec(const char *enc, char **codec) { char *tmp; Py_ssize_t size; PyObject *pyenc = NULL; int rv = -1; /* Find the Py codec name from the PG encoding */ if (!(pyenc = PyDict_GetItemString(psycoEncodings, enc))) { PyErr_Format(OperationalError, "no Python codec for client encoding '%s'", enc); goto exit; } /* Convert the codec in a bytes string to extract the c string. */ Py_INCREF(pyenc); if (!(pyenc = psycopg_ensure_bytes(pyenc))) { goto exit; } if (-1 == Bytes_AsStringAndSize(pyenc, &tmp, &size)) { goto exit; } /* have our own copy of the python codec name */ rv = psycopg_strdup(codec, tmp, size); exit: Py_XDECREF(pyenc); return rv; }
static PyObject * psyco_lobj_write(lobjectObject *self, PyObject *args) { char *buffer; Py_ssize_t len; Py_ssize_t res; PyObject *obj; PyObject *data = NULL; PyObject *rv = NULL; if (!PyArg_ParseTuple(args, "O", &obj)) return NULL; EXC_IF_LOBJ_CLOSED(self); EXC_IF_LOBJ_LEVEL0(self); EXC_IF_LOBJ_UNMARKED(self); if (Bytes_Check(obj)) { Py_INCREF(obj); data = obj; } else if (PyUnicode_Check(obj)) { if (!(data = PyUnicode_AsEncodedString(obj, self->conn->codec, NULL))) { goto exit; } } else { PyErr_Format(PyExc_TypeError, "lobject.write requires a string; got %s instead", Py_TYPE(obj)->tp_name); goto exit; } if (-1 == Bytes_AsStringAndSize(data, &buffer, &len)) { goto exit; } if (0 > (res = lobject_write(self, buffer, (size_t)len))) { goto exit; } rv = PyInt_FromLong((long)res); exit: Py_XDECREF(data); return rv; }
static PyObject * qstring_quote(qstringObject *self) { PyObject *str = NULL; char *s, *buffer = NULL; Py_ssize_t len, qlen; const char *encoding = default_encoding; PyObject *rv = NULL; /* if the wrapped object is an unicode object we can encode it to match conn->encoding but if the encoding is not specified we don't know what to do and we raise an exception */ if (self->conn) { encoding = self->conn->codec; } Dprintf("qstring_quote: encoding to %s", encoding); if (PyUnicode_Check(self->wrapped) && encoding) { str = PyUnicode_AsEncodedString(self->wrapped, encoding, NULL); Dprintf("qstring_quote: got encoded object at %p", str); if (str == NULL) goto exit; } #if PY_MAJOR_VERSION < 3 /* if the wrapped object is a simple string, we don't know how to (re)encode it, so we pass it as-is */ else if (PyString_Check(self->wrapped)) { str = self->wrapped; /* INCREF to make it ref-wise identical to unicode one */ Py_INCREF(str); } #endif /* if the wrapped object is not a string, this is an error */ else { PyErr_SetString(PyExc_TypeError, "can't quote non-string object (or missing encoding)"); goto exit; } /* encode the string into buffer */ Bytes_AsStringAndSize(str, &s, &len); if (!(buffer = psycopg_escape_string(self->conn, s, len, NULL, &qlen))) { goto exit; } if (qlen > (size_t) PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_IndexError, "PG buffer too large to fit in Python buffer."); goto exit; } rv = Bytes_FromStringAndSize(buffer, qlen); exit: PyMem_Free(buffer); Py_XDECREF(str); return rv; }