8
8
namespace pybind11 {
9
9
namespace detail {
10
10
11
- template <typename Char , typename Traits, size_t N>
12
- struct type_caster <wpi::ct_string<Char , Traits, N>> {
13
- using str_type = wpi::ct_string<Char , Traits, N>;
11
+ template <typename CharT , typename Traits, size_t N>
12
+ struct type_caster <wpi::ct_string<CharT , Traits, N>> {
13
+ using str_type = wpi::ct_string<CharT , Traits, N>;
14
14
PYBIND11_TYPE_CASTER (str_type, const_name(PYBIND11_STRING_NAME));
15
15
16
16
// TODO
@@ -21,19 +21,35 @@ struct type_caster<wpi::ct_string<Char, Traits, N>> {
21
21
static handle cast (const str_type& src,
22
22
py::return_value_policy policy,
23
23
py::handle parent) {
24
- const char *buffer = reinterpret_cast <const char *>(src.data ());
25
- auto nbytes = ssize_t (src.size () * sizeof (Char));
26
- handle s;
27
- if (policy == return_value_policy::_return_as_bytes) {
28
- s = PyBytes_FromStringAndSize (buffer, nbytes);
29
- } else {
30
- s = PyUnicode_DecodeUTF8 (buffer, nbytes, nullptr );
31
- }
24
+ const char *buffer = reinterpret_cast <const char *>(src.data ());
25
+ auto nbytes = ssize_t (src.size () * sizeof (CharT));
26
+ handle s = decode_utfN (buffer, nbytes);
32
27
if (!s) {
33
28
throw error_already_set ();
34
29
}
35
30
return s;
36
- }
31
+ }
32
+
33
+ // copied from py::string_caster
34
+ static constexpr size_t UTF_N = 8 * sizeof (CharT);
35
+
36
+ static handle decode_utfN (const char *buffer, ssize_t nbytes) {
37
+ #if !defined(PYPY_VERSION)
38
+ return UTF_N == 8 ? PyUnicode_DecodeUTF8 (buffer, nbytes, nullptr )
39
+ : UTF_N == 16 ? PyUnicode_DecodeUTF16 (buffer, nbytes, nullptr , nullptr )
40
+ : PyUnicode_DecodeUTF32 (buffer, nbytes, nullptr , nullptr );
41
+ #else
42
+ // PyPy segfaults when on PyUnicode_DecodeUTF16 (and possibly on PyUnicode_DecodeUTF32 as
43
+ // well), so bypass the whole thing by just passing the encoding as a string value, which
44
+ // works properly:
45
+ return PyUnicode_Decode (buffer,
46
+ nbytes,
47
+ UTF_N == 8 ? " utf-8"
48
+ : UTF_N == 16 ? " utf-16"
49
+ : " utf-32" ,
50
+ nullptr );
51
+ #endif
52
+ }
37
53
38
54
};
39
55
0 commit comments