utils: allow borrowing a C string
We don't always need our own copy of a C string; sometimes we just need to parse it. Create py_str_borrow_c_str() which returns a char pointer to python's internal value string, with which we can avoid an extra copy.
This commit is contained in:
43
src/utils.c
43
src/utils.c
@@ -32,27 +32,50 @@
|
||||
|
||||
extern PyTypeObject ReferenceType;
|
||||
|
||||
/* py_str_to_c_str() returns a newly allocated C string holding
|
||||
* the string contained in the value argument. */
|
||||
/**
|
||||
* py_str_to_c_str() returns a newly allocated C string holding the string
|
||||
* contained in the 'value' argument.
|
||||
*/
|
||||
char *
|
||||
py_str_to_c_str(PyObject *value, const char *encoding)
|
||||
{
|
||||
const char *borrowed;
|
||||
char *c_str = NULL;
|
||||
PyObject *tmp = NULL;
|
||||
|
||||
borrowed = py_str_borrow_c_str(&tmp, value, encoding);
|
||||
if (!borrowed)
|
||||
return NULL;
|
||||
|
||||
c_str = strdup(borrowed);
|
||||
|
||||
Py_DECREF(tmp);
|
||||
return c_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a pointer to the underlying C string in 'value'. The pointer is
|
||||
* guaranteed by 'tvalue'. Decrease its refcount when done with the string.
|
||||
*/
|
||||
const char *
|
||||
py_str_borrow_c_str(PyObject **tvalue, PyObject *value, const char *encoding)
|
||||
{
|
||||
/* Case 1: byte string */
|
||||
if (PyBytes_Check(value))
|
||||
return strdup(PyBytes_AsString(value));
|
||||
if (PyBytes_Check(value)) {
|
||||
Py_INCREF(value);
|
||||
*tvalue = value;
|
||||
return PyBytes_AsString(value);
|
||||
}
|
||||
|
||||
/* Case 2: text string */
|
||||
if (PyUnicode_Check(value)) {
|
||||
if (encoding == NULL)
|
||||
value = PyUnicode_AsUTF8String(value);
|
||||
*tvalue = PyUnicode_AsUTF8String(value);
|
||||
else
|
||||
value = PyUnicode_AsEncodedString(value, encoding, "strict");
|
||||
if (value == NULL)
|
||||
*tvalue = PyUnicode_AsEncodedString(value, encoding, "strict");
|
||||
if (*tvalue == NULL)
|
||||
return NULL;
|
||||
c_str = strdup(PyBytes_AsString(value));
|
||||
Py_DECREF(value);
|
||||
return c_str;
|
||||
return PyBytes_AsString(*tvalue);
|
||||
}
|
||||
|
||||
/* Type error */
|
||||
|
@@ -108,6 +108,8 @@ to_bytes(const char * value)
|
||||
}
|
||||
|
||||
char * py_str_to_c_str(PyObject *value, const char *encoding);
|
||||
const char *py_str_borrow_c_str(PyObject **tvaue, PyObject *value, const char *encoding);
|
||||
|
||||
|
||||
#define py_path_to_c_str(py_path) \
|
||||
py_str_to_c_str(py_path, Py_FileSystemDefaultEncoding)
|
||||
|
Reference in New Issue
Block a user