#include "pybind11/pybind11.h" #include "pybind11/stl.h" #include /**< std::stringstream */ #include /**< memmove */ #include "dbcc/dbc_iterator.h" #include "dbcc/message.h" #include "dbcc/signal.h" #include "dbcc/version.h" using namespace pybind11; PYBIND11_MODULE(_dbcc, m) { m.def("version", &ad::dbcc::version); enum_(m, "ByteOrder") .value("Motorola", ad::dbcc::ByteOrder::Motorola) .value("Intel", ad::dbcc::ByteOrder::Intel) .export_values(); enum_(m, "Sign") .value("Unsigned", ad::dbcc::Sign::Unsigned) .value("Signed", ad::dbcc::Sign::Signed) .export_values(); enum_(m, "Multiplexor") .value("None", ad::dbcc::Multiplexor::None) .value("Multiplexed", ad::dbcc::Multiplexor::Multiplexed) .value("Multiplexor", ad::dbcc::Multiplexor::Multiplexor) .export_values(); class_(m, "SignalLayoutInfo") .def_readonly("bits", &ad::dbcc::Signal::LayoutInfo::bits) .def_readonly("byte_lines", &ad::dbcc::Signal::LayoutInfo::byteLines) .def_readonly("byte_line_range", &ad::dbcc::Signal::LayoutInfo::byteLineRange); class_(m, "Signal") .def("__str__", [](ad::dbcc::Signal &sig) { std::stringstream ss; ss << "Signal(" << sig.name() << "[" << (sig.isFloat() ? "float" : "int") << "]: " << sig.startBit() << "," << sig.length() << " " << "(" << sig.factor() << "," << sig.offset() << ") " << "[" << sig.minimum() << "," << sig.maximum() << "]"; return ss.str(); }) .def("__repr__", [](ad::dbcc::Signal &s) { std::stringstream ss; ss << ""; return ss.str(); }) .def("encode", [](ad::dbcc::Signal &sig, double value, bytearray &ba) { Py_buffer buffer; if (PyObject_GetBuffer(ba.ptr(), &buffer, PyBUF_WRITABLE) < 0) { return; } sig.encode(value, reinterpret_cast(buffer.buf), buffer.len); PyBuffer_Release(&buffer); }) .def("decode", [](ad::dbcc::Signal &sig, bytearray &ba) -> double { double ret = 0; Py_buffer buffer; if (PyObject_GetBuffer(ba.ptr(), &buffer, PyBUF_SIMPLE) == 0) { sig.decode(reinterpret_cast(buffer.buf), buffer.len, ret); PyBuffer_Release(&buffer); } return ret; }) .def("bits_layout", [](ad::dbcc::Signal &sig) -> ad::dbcc::Signal::LayoutInfo { ad::dbcc::Signal::LayoutInfo ret; sig.bitsLayout(ret); return ret; }) .def_property_readonly("name", &ad::dbcc::Signal::name) .def_property_readonly("byte_order", &ad::dbcc::Signal::byteOrder) .def_property_readonly("start_bit", &ad::dbcc::Signal::startBit) .def_property_readonly("length", &ad::dbcc::Signal::length) .def_property_readonly("sign", &ad::dbcc::Signal::sign) .def_property_readonly("min", &ad::dbcc::Signal::minimum) .def_property_readonly("max", &ad::dbcc::Signal::maximum) .def_property_readonly("factor", &ad::dbcc::Signal::factor) .def_property_readonly("offset", &ad::dbcc::Signal::offset) .def_property_readonly("unit", &ad::dbcc::Signal::unit) .def_property_readonly("is_float", &ad::dbcc::Signal::isFloat) .def_property_readonly("multiplexor", &ad::dbcc::Signal::multiplexor) .def_property_readonly("multiplexed_num", &ad::dbcc::Signal::multiplexedNumber) .def_property_readonly("to", &ad::dbcc::Signal::to); class_(m, "Message") .def("__len__", &ad::dbcc::Message::size) /* Essential: keep object alive while iterator exists */ .def("__iter__", [](ad::dbcc::Message &s) { return make_iterator(s.begin(), s.end()); }, keep_alive<0, 1>()) .def("__getitem__", [](ad::dbcc::Message &s, size_t i) { if (i >= s.size()) { throw index_error(); } return s[i]; }) .def("__str__", [](ad::dbcc::Message &s) { std::stringstream ss; ss << "Message(" << s.name() << "[0x" << std::hex << s.id() << std::dec << ", " << s.id() << "])"; return ss.str(); }) .def("__repr__", [](ad::dbcc::Message &s) { std::stringstream ss; ss << ""; return ss.str(); }) .def_property_readonly("name", &ad::dbcc::Message::name) .def_property_readonly("id", &ad::dbcc::Message::id) .def_property_readonly("dlc", &ad::dbcc::Message::dlc) .def_property_readonly("from", &ad::dbcc::Message::from) .def_property_readonly("to", &ad::dbcc::Message::to); class_(m, "DbcParser") .def(init()) .def("__len__", &ad::dbcc::DbcIterator::size) /* Essential: keep object alive while iterator exists */ .def("__iter__", [](ad::dbcc::DbcIterator &s) { return make_iterator(s.begin(), s.end()); }, keep_alive<0, 1>()) .def("__getitem__", [](ad::dbcc::DbcIterator &s, size_t i) { if (i >= s.size()) { throw index_error(); } return s[i]; }); }