Working type casters for wide strings and wide characters

This commit is contained in:
Wenzel Jakob
2016-03-08 19:40:32 +01:00
5 changed files with 66 additions and 20 deletions

View File

@@ -349,22 +349,45 @@ public:
PYBIND11_TYPE_CASTER(std::string, _(PYBIND11_STRING_NAME));
};
template <> class type_caster<char> {
template <> class type_caster<std::wstring> {
public:
bool load(handle src, bool) {
object temp;
handle load_src = src;
if (PyUnicode_Check(load_src.ptr())) {
temp = object(PyUnicode_AsUTF8String(load_src.ptr()), false);
if (!temp) { PyErr_Clear(); return false; } // UnicodeEncodeError
load_src = temp;
bool load(handle src, bool) {
object temp;
handle load_src = src;
if (!PyUnicode_Check(load_src.ptr())) {
temp = object(PyUnicode_FromObject(load_src.ptr()), false);
if (!temp) { PyErr_Clear(); return false; }
load_src = temp;
}
wchar_t *buffer = nullptr;
ssize_t length = -1;
#if PY_MAJOR_VERSION >= 3
buffer = PyUnicode_AsWideCharString(load_src.ptr(), &length);
#else
temp = object(
sizeof(wchar_t) == sizeof(short)
? PyUnicode_AsUTF16String(load_src.ptr())
: PyUnicode_AsUTF32String(load_src.ptr()), false);
if (temp) {
int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), (char **) &buffer, &length);
if (err == -1) { buffer = nullptr; } // TypeError
length = length / sizeof(wchar_t) - 1; ++buffer; // Skip BOM
}
const char *ptr = PYBIND11_BYTES_AS_STRING(load_src.ptr());
if (!ptr) { PyErr_Clear(); return false; } // TypeError
value = std::string(ptr);
return true;
}
#endif
if (!buffer) { PyErr_Clear(); return false; }
value = std::wstring(buffer, length);
return true;
}
static handle cast(const std::wstring &src, return_value_policy /* policy */, handle /* parent */) {
return PyUnicode_FromWideChar(src.c_str(), src.length());
}
PYBIND11_TYPE_CASTER(std::wstring, _(PYBIND11_STRING_NAME));
};
template <> class type_caster<char> : public type_caster<std::string> {
public:
static handle cast(const char *src, return_value_policy /* policy */, handle /* parent */) {
return PyUnicode_FromString(src);
}
@@ -382,6 +405,25 @@ protected:
std::string value;
};
template <> class type_caster<wchar_t> : public type_caster<std::wstring> {
public:
static handle cast(const wchar_t *src, return_value_policy /* policy */, handle /* parent */) {
return PyUnicode_FromWideChar(src, wcslen(src));
}
static handle cast(wchar_t src, return_value_policy /* policy */, handle /* parent */) {
wchar_t wstr[2] = { src, L'\0' };
return PyUnicode_FromWideChar(wstr, 1);
}
operator wchar_t*() { return (wchar_t *)value.c_str(); }
operator wchar_t() { if (value.length() > 0) return value[0]; else return L'\0'; }
static PYBIND11_DESCR name() { return type_descr(_(PYBIND11_STRING_NAME)); }
protected:
std::wstring value;
};
template <typename T1, typename T2> class type_caster<std::pair<T1, T2>> {
typedef std::pair<T1, T2> type;
public: