Skip to content

Instantly share code, notes, and snippets.

@zooba
Created December 2, 2024 13:12
Show Gist options
  • Select an option

  • Save zooba/a13e1671f4ef4867e24e2fbfcdec18fb to your computer and use it in GitHub Desktop.

Select an option

Save zooba/a13e1671f4ef4867e24e2fbfcdec18fb to your computer and use it in GitHub Desktop.
A CPython PyArg_Parse converter for UTF-16 strings
#include <Python.h>
#include <windows.h>
int as_utf16(PyObject *obj, wchar_t **address) {
if (obj == NULL) {
// Automatic cleanup
PyMem_Free(*address);
return 1;
}
PyObject *wobj = PyObject_Str(obj);
if (!wobj) {
return 0;
}
PyObject *b = PyObject_CallMethod(wobj, "encode", "ss", "utf-16-le", "strict");
Py_DECREF(wobj);
if (!b) {
return 0;
}
char *src;
Py_ssize_t len;
if (PyBytes_AsStringAndSize(b, &src, &len) < 0) {
Py_DECREF(b);
return 0;
}
Py_ssize_t wlen = len / sizeof(wchar_t);
wchar_t *result = (wchar_t *)PyMem_Malloc((wlen + 1) * sizeof(wchar_t));
if (!result) {
Py_DECREF(b);
return 0;
}
wcsncpy_s(result, wlen + 1, (wchar_t *)src, wlen);
Py_DECREF(b);
*address = result;
return Py_CLEANUP_SUPPORTED;
}
#include <Python.h>
PyObject *urlopen(PyObject *, PyObject *args, PyObject *kwargs) {
static const char * keywords[] = {"url", "method", "headers", "accepts", NULL};
wchar_t *url = NULL;
wchar_t *method = NULL;
wchar_t *headers = NULL;
wchar_t *accepts = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&O&:urlopen", keywords,
as_utf16, &url, as_utf16, &method, as_utf16, &headers, as_utf16, &accepts)) {
return NULL;
}
// function body
PyMem_Free(accepts);
PyMem_Free(headers);
PyMem_Free(method);
PyMem_Free(url);
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment