# distutils: language = c++ # cython: language_level=3 from cython.operator cimport dereference as deref, preincrement as preinc from libcpp.vector cimport vector from libcpp.string cimport string from libcpp cimport bool from libc.stdint cimport uint8_t, uint32_t, uint64_t cdef extern from "opendbc/can/common.h": cdef struct CanFrame: long src uint32_t address vector[uint8_t] dat cdef struct CanData: uint64_t nanos vector[CanFrame] frames cdef extern from "can_list_to_can_capnp.cc": void can_list_to_can_capnp_cpp(const vector[CanFrame] &can_list, string &out, bool sendcan, bool valid) nogil void can_capnp_to_can_list_cpp(const vector[string] &strings, vector[CanData] &can_data, bool sendcan) def can_list_to_can_capnp(can_msgs, msgtype='can', valid=True): cdef CanFrame *f cdef vector[CanFrame] can_list cdef uint32_t cpp_can_msgs_len = len(can_msgs) with nogil: can_list.reserve(cpp_can_msgs_len) for can_msg in can_msgs: f = &(can_list.emplace_back()) f.address = can_msg[0] f.dat = can_msg[1] f.src = can_msg[2] cdef string out cdef bool is_sendcan = (msgtype == 'sendcan') cdef bool is_valid = valid with nogil: can_list_to_can_capnp_cpp(can_list, out, is_sendcan, is_valid) return out def can_capnp_to_list(strings, msgtype='can'): cdef vector[CanData] data can_capnp_to_can_list_cpp(strings, data, msgtype == 'sendcan') result = [] cdef CanData *d cdef vector[CanData].iterator it = data.begin() while it != data.end(): d = &deref(it) frames = [(f.address, (&f.dat[0])[:f.dat.size()], f.src) for f in d.frames] result.append((d.nanos, frames)) preinc(it) return result