|
32 | 32 | #ifndef PYBIND11_ABSEIL_ABSL_CASTERS_H_
|
33 | 33 | #define PYBIND11_ABSEIL_ABSL_CASTERS_H_
|
34 | 34 |
|
| 35 | +#include <Python.h> |
35 | 36 | #include <pybind11/cast.h>
|
36 | 37 | #include <pybind11/pybind11.h>
|
37 | 38 | #include <pybind11/stl.h>
|
|
45 | 46 | #include <cstring>
|
46 | 47 | #include <tuple>
|
47 | 48 | #include <type_traits>
|
| 49 | +#include <utility> |
48 | 50 | #include <vector>
|
49 | 51 |
|
50 | 52 | #include "absl/cleanup/cleanup.h"
|
@@ -618,10 +620,39 @@ struct type_caster<absl::Cord> {
|
618 | 620 |
|
619 | 621 | // Conversion part 1 (Python->C++)
|
620 | 622 | bool load(handle src, bool convert) {
|
| 623 | + // If the source is a bytes/string object, we can avoid a copy by using |
| 624 | + // absl::MakeCordFromExternal. |
| 625 | + absl::optional<absl::string_view> view; |
| 626 | + if (PyUnicode_Check(src.ptr())) { |
| 627 | + Py_ssize_t size = 0; |
| 628 | + const char* data = PyUnicode_AsUTF8AndSize(src.ptr(), &size); |
| 629 | + if (data) { |
| 630 | + view = absl::string_view(data, size); |
| 631 | + } else { |
| 632 | + PyErr_Clear(); |
| 633 | + } |
| 634 | + } else if (PyBytes_Check(src.ptr())) { |
| 635 | + view = absl::string_view(PyBytes_AS_STRING(src.ptr()), |
| 636 | + PyBytes_GET_SIZE(src.ptr())); |
| 637 | + } |
| 638 | + if (view.has_value()) { |
| 639 | + if (!view->empty()) { |
| 640 | + // Bypass StringViewCaster life support as absl::Cord may outlive the |
| 641 | + // handle. |
| 642 | + src.inc_ref(); |
| 643 | + value = absl::MakeCordFromExternal(*view, [src] { |
| 644 | + PyGILState_STATE gstate = PyGILState_Ensure(); |
| 645 | + src.dec_ref(); |
| 646 | + PyGILState_Release(gstate); |
| 647 | + }); |
| 648 | + } else { |
| 649 | + value.Clear(); |
| 650 | + } |
| 651 | + return true; |
| 652 | + } |
621 | 653 | auto caster = StringViewCaster();
|
622 | 654 | if (caster.load(src, convert)) {
|
623 |
| - absl::string_view view = cast_op<absl::string_view>(std::move(caster)); |
624 |
| - value = view; |
| 655 | + value = absl::Cord(cast_op<absl::string_view>(std::move(caster))); |
625 | 656 | return true;
|
626 | 657 | }
|
627 | 658 | return false;
|
|
0 commit comments