{"id":13741300,"url":"https://github.com/xR3b0rn/dbcppp","last_synced_at":"2025-05-08T21:33:41.848Z","repository":{"id":37573329,"uuid":"181325142","full_name":"xR3b0rn/dbcppp","owner":"xR3b0rn","description":"C/C++ DBC file parser/tool","archived":false,"fork":false,"pushed_at":"2024-07-24T09:01:30.000Z","size":10333,"stargazers_count":222,"open_issues_count":20,"forks_count":71,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-08-04T04:07:37.895Z","etag":null,"topics":["command-line-tool","dbc","kcd","parser"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xR3b0rn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-14T14:57:38.000Z","updated_at":"2024-08-02T13:56:11.000Z","dependencies_parsed_at":"2024-05-18T18:44:15.115Z","dependency_job_id":null,"html_url":"https://github.com/xR3b0rn/dbcppp","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xR3b0rn%2Fdbcppp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xR3b0rn%2Fdbcppp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xR3b0rn%2Fdbcppp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xR3b0rn%2Fdbcppp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xR3b0rn","download_url":"https://codeload.github.com/xR3b0rn/dbcppp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224774752,"owners_count":17367790,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["command-line-tool","dbc","kcd","parser"],"created_at":"2024-08-03T04:00:57.636Z","updated_at":"2024-11-15T11:31:10.680Z","avatar_url":"https://github.com/xR3b0rn.png","language":"C++","funding_links":[],"categories":["CAN Database"],"sub_categories":["DBC only"],"readme":"[![Build Status](https://github.com/xR3b0rn/dbcppp/actions/workflows/linux.yml/badge.svg?branch=master)\n# dbcppp\nA C/C++ DBC file parser based on `boost.spirit`. This library is designed for decoding performance.\n# Features\n* very fast decoding\n* verbose parser output in error case\n* DBC is editable through C/C++ interface exported from the library\n* read/write DBC file\n* decode functionality for frames of arbitrarily byte length\n* [cantools](https://github.com/eerimoq/cantools) like decoding\n* [KCD](https://github.com/julietkilo/kcd) file format support\n\n\n# Getting started\n## Build \u0026 Install\n```\ngit clone --recurse-submodules https://github.com/xR3b0rn/dbcppp.git\ncd dbcppp\nmkdir build\ncd build\ncmake -DCMAKE_BUILD_TYPE=Release ..\nmake -j\nmake RunTests\nmake install\nldconfig # on Unix-systems only\n```\n\n# Usage example\n## Command line tool\n### dbc2\n```\n# generate C source from DBC/KCD\ndbcparser dbc2 --dbc=file.dbc --format=C\n# beauty or merge DBC/KCD\ndbcparser dbc2 --dbc=file1.dbc --dbc=file2.kcd --format=DBC\n# print DBC/KCD in human readable format\ndbcparser dbc2 --dbc=file1.dbc --dbc=file2.kcd --format=human\n```\n### decode\n[cantools](https://github.com/eerimoq/cantools) like decoding:\n```\ncandump any | dbcppp decode --bus=vcan0,file1.dbc --bus=vcan1,file2.dbc\n```\n## Library\n* [Examples](https://github.com/xR3b0rn/dbcppp/tree/master/examples)\n* `C++`\n```C++\n#include \u003cfstream\u003e\n#include \u003cdbcppp/Network.h\u003e\nint main()\n{\n    std::unique_ptr\u003cdbcppp::INetwork\u003e net;\n    {\n        std::ifstream idbc(\"your.dbc\");\n        net = dbcppp::INetwork::LoadDBCFromIs(idbc);\n    }\n    std::unordered_map\u003cuint64_t, const dbcppp::IMessage*\u003e messages;\n    for (const dbcppp::IMessage\u0026 msg : net-\u003eMessages())\n    {\n        messages.insert(std::make_pair(msg.Id(), \u0026msg));\n    }\n    can_frame frame;\n    while (1)\n    {\n        receive_frame_data(\u0026frame);\n        auto iter = messages.find(frame.can_id);\n        if (iter != messages.end())\n        {\n            const dbcppp::IMessage* msg = iter-\u003esecond;\n            std::cout \u003c\u003c \"Received Message: \" \u003c\u003c msg-\u003eName() \u003c\u003c \"\\n\";\n            for (const dbcppp::ISignal\u0026 sig : msg-\u003eSignals())\n            {\n                const dbcppp::ISignal* mux_sig = msg-\u003eMuxSignal();\n                if (sig.MultiplexerIndicator() != dbcppp::ISignal::EMultiplexer::MuxValue ||\n                    (mux_sig \u0026\u0026 mux_sig-\u003eDecode(frame.data) == sig.MultiplexerSwitchValue()))\n                {\n                    std::cout \u003c\u003c \"\\t\" \u003c\u003c sig.Name() \u003c\u003c \"=\" \u003c\u003c sig.RawToPhys(sig.Decode(frame.data)) \u003c\u003c sig.Unit() \u003c\u003c \"\\n\";\n                }\n            }\n        }\n    }\n}\n```\n* `C`\n```C\n#include \u003cstdio.h\u003e\n#include \u003cdbcppp/CApi.h\u003e\nint main()\n{\n    const dbcppp_Nework* net = dbcppp_NetworkLoadDBCFromFile(\"your.dbc\");\n    if (net)\n    {\n        can_frame frame;\n        while (1)\n        {\n            receive_can_frame_from_somewhere(\u0026frame);\n            const dbcppp_Message* msg = nullptr;\n            auto n_msgs = dbcppp_NetworkMessages_Size(net);\n            for (uint64_t i = 0; i \u003c n_msgs; i++)\n            {\n                const dbcppp_Message* msg = dbcppp_NetworkMessages_Get(i);\n                if (dbcppp_MessageId(tmp) == frame.can_id)\n                {\n                    printf(\"Received message: %s\\n\", dbcppp_MessageGetName(msg));\n                    dbcppp_MessageForEachSignal(msg, print_signal_data, \u0026frame);\n                    for (uint64_t i = 0; i \u003c dbcppp_MessageSignals_Size(msg); i++)\n                    {\n                        const dbcppp_Signal* sig = dbcppp_MessageSignals_Get(msg, i);\n                        uint64_t raw = dbcppp_SignalDecode(sig, frame.data);\n                        double phys = dbcppp_SignalRawToPhys(sig, raw);\n                        printf(\"\\t%s=%f\\n\", dbcppp_SignalName(sig), phys);\n                    }\n                }\n            }\n        }\n    }\n    dbcppp_NetworkFree(net);\n}\n```\n# DBC data types\n## Supported\n* version\n* new_symbols\n* bit_timing\n* nodes\n* value_tables\n* messages\n* message_transmitters\n* environment_variables\n* environment_variables_data\n* signal_types\n* comments\n* attribute_definitions\n* attribute_defaults\n* attribute_values\n* value_descriptions\n* signal_extended_value_type_list\n* signal_groups\n* signal_multiplexer_value\n## Not supported yet\n* sigtype_attr_list\n* signal_type_refs\n# Decode-function\nThe signals decode function is using prestored masks and fixed offsets to speed up calculation, therefore the decoding-function should be almost as fast as a code generated decode function would be. The assembly of the `decode`-function on its critical path (signed and byte swap must happen) looks like this (VS19 10.0.18362.0 compiler):\n```\ntemplate \u003cAlignment aAlignment, Signal::ByteOrder aByteOrder, Signal::ValueType aValueType, Signal::ExtendedValueType aExtendedValueType\u003e\ndouble template_decode(const Signal* sig, const void* nbytes) noexcept\n00007FF8025BCA73  mov         rax,rcx  \n00007FF8025BCA76  mov         rcx,qword ptr [rcx+140h]  \n00007FF8025BCA7D  xorps       xmm0,xmm0  \n00007FF8025BCA80  bswap       r8  \n00007FF8025BCA83  shr         r8,cl  \n00007FF8025BCA86  and         r8,qword ptr [rax+130h]  \n00007FF8025BCA8D  mov         rcx,qword ptr [rax+138h]  \n00007FF8025BCA94  mov         rax,rcx  \n00007FF8025BCA97  or          rcx,r8  \n00007FF8025BCA9A  and         rax,r8  \n00007FF8025BCA9D  cmove       rcx,r8  \n00007FF8025BCAA1  cvtsi2sd    xmm0,rcx  \n00007FF8025BCAA6  ret   \n```\nOn the best path (no byteswap must take place and ExtendedValueType == Double) the decode function only has 5 instructions:\n```\ntemplate \u003cAlignment aAlignment, Signal::ByteOrder aByteOrder, Signal::ValueType aValueType, Signal::ExtendedValueType aExtendedValueType\u003e\ndouble template_decode(const Signal* sig, const void* nbytes) noexcept\n00007FF8025BCAF0  mov         rax,qword ptr [rdx]  \n00007FF8025BCAF3  mov         qword ptr [rsp+8],rcx  \n00007FF8025BCAF8  mov         qword ptr [sig],rax  \n00007FF8025BCAFD  movsd       xmm0,mmword ptr [data]  \n00007FF8025BCB03  ret  \n```\n# Known issues\n* tests for decoding function for float/double is failing on some machines (currently only confirmed for System/s390x)\n# Similar projects\n  * [Vector_DBC](https://bitbucket.org/tobylorenz/vector_dbc/src/master/) Does basically the same, the biggest difference is that it uses `bison` instead of `boost::spirit` for grammar parsing\n  * [CAN BUS tools in Python 3 (cantools)](https://github.com/eerimoq/cantools) \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FxR3b0rn%2Fdbcppp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FxR3b0rn%2Fdbcppp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FxR3b0rn%2Fdbcppp/lists"}