Skip to content

Commit

Permalink
Add type_caster for ntcore raw values
Browse files Browse the repository at this point in the history
- std::vector<uint8_t> is only used in raw contexts, so the type caster
  intercepts and converts the value automatically to/from bytes
- Fixes #45
- There may be other places we could use this technique?
  • Loading branch information
virtuald committed Dec 18, 2023
1 parent c476a8a commit 5349098
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 0 deletions.
3 changes: 3 additions & 0 deletions subprojects/pyntcore/gen/GenericEntry.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
---

extra_includes:
- src/nt_type_caster.h

classes:
GenericSubscriber:
methods:
Expand Down
3 changes: 3 additions & 0 deletions subprojects/pyntcore/gen/RawTopic.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
---

extra_includes:
- src/nt_type_caster.h

classes:
RawSubscriber:
methods:
Expand Down
3 changes: 3 additions & 0 deletions subprojects/pyntcore/gen/ntcore_cpp_types.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
---

extra_includes:
- src/nt_type_caster.h

defaults:
ignore: true
report_ignored_missing: false
Expand Down
39 changes: 39 additions & 0 deletions subprojects/pyntcore/ntcore/src/nt_type_caster.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#pragma once

#include <pybind11/pybind11.h>

namespace pybind11 {
namespace detail {

// ntcore uses std::vector<uint8_t> anytime there is a raw value, so
// add this specialization to convert to/from bytes directly

template<>
struct type_caster<std::vector<uint8_t>> {
using vector_type = std::vector<uint8_t>;
PYBIND11_TYPE_CASTER(vector_type, const_name("bytes"));

bool load(handle src, bool convert) {
if (!isinstance<buffer>(src)) {
return false;
}
auto buf = reinterpret_borrow<buffer>(src);
auto req = buf.request();
if (req.ndim != 1) {
return false;
}

auto begin = (const uint8_t*)req.ptr;
auto end = begin + req.size*req.itemsize;

value = std::vector<uint8_t>(begin, end);
return true;
}

static handle cast(const std::vector<uint8_t> &src, return_value_policy policy, handle parent) {
return py::bytes((char*)src.data(), src.size()).release();
}
};

}
}

0 comments on commit 5349098

Please sign in to comment.