#include "pybind11/pybind11.h" #include "pybind11/stl.h" #include /**< memmove */ #include /**< std::stringstream */ #include "dbcc/dbc_iterator.h" #include "dbcc/message.h" #include "dbcc/signal.h" #include "dbcc/helper/gen_helper.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::kMotorola) .value("Intel", ad::dbcc::ByteOrder::kIntel) .export_values(); enum_(m, "Sign") .value("Unsigned", ad::dbcc::Sign::kUnsigned) .value("Signed", ad::dbcc::Sign::kSigned) .export_values(); enum_(m, "Multiplexor") .value("None", ad::dbcc::Multiplexor::kNone) .value("Multiplexed", ad::dbcc::Multiplexor::kMultiplexed) .value("Multiplexor", ad::dbcc::Multiplexor::kMultiplexor) .export_values(); class_(m, "SignalLayoutInfo") .def_readonly("bits", &ad::dbcc::Signal::LayoutInfo::bits) .def_readonly("byte_lines", &ad::dbcc::Signal::LayoutInfo::byte_lines) .def_readonly("byte_line_range", &ad::dbcc::Signal::LayoutInfo::byte_line_range); 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("dbc_str", [](ad::dbcc::Signal& sig) { std::stringstream ss; ss << sig; 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::GetByteOrder) .def_property_readonly("start_bit", &ad::dbcc::Signal::StartBit) .def_property_readonly("length", &ad::dbcc::Signal::Length) .def_property_readonly("sign", &ad::dbcc::Signal::GetSign) .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::GetMultiplexor) .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::SignalCount) /* 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.SignalCount()) { 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("dbc_str", [](ad::dbcc::Message& m) { std::stringstream ss; ss << m; 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]; }); class_(m, "GenHelper") .def(init()) .def("gen_all", [](ad::dbcc::helper::GenHelper &gen_helper) { return gen_helper.GenAll(); }) .def("gen_msg_def", [](ad::dbcc::helper::GenHelper &gen_helper, const std::string &msg, int indent_level) { return gen_helper.GenMessageDef(msg, indent_level); }) .def("gen_msg_unpack_decl", [](ad::dbcc::helper::GenHelper &gen_helper, const std::string &msg, int indent_level) { return gen_helper.GenMessageUnpackDecl(msg, indent_level); }) .def("gen_msg_unpack_def", [](ad::dbcc::helper::GenHelper &gen_helper, const std::string &msg, int indent_level) { return gen_helper.GenMessageUnpackDef(msg, indent_level); }) .def("gen_msg_pack_decl", [](ad::dbcc::helper::GenHelper &gen_helper, const std::string &msg, int indent_level) { return gen_helper.GenMessagePackDecl(msg, indent_level); }) .def("gen_msg_pack_def", [](ad::dbcc::helper::GenHelper &gen_helper, const std::string &msg, int indent_level) { return gen_helper.GenMessagePackDef(msg, indent_level); }) .def("gen_macros", [](ad::dbcc::helper::GenHelper &gen_helper) { return ad::dbcc::helper::GenHelper::GenMacros(); }); }