Skip to content

Commit 0f3b22b

Browse files
authored
Merge pull request #17 from Murmele/parseNonByteAlignedNumber
Parse non byte aligned number
2 parents a3b941a + f1409c6 commit 0f3b22b

File tree

6 files changed

+83
-17
lines changed

6 files changed

+83
-17
lines changed

CMakeLists.txt

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ include(CPack)
1414

1515
option(DEBUG "use debug flag" NO)
1616
option(ENABLE_TESTS "Enable Unittests" ON)
17+
# Turn OFF, if you are using FetchContent to include it to your project
18+
option(FETCH_CONTENT_INCLUSION "Include project with FetchContent_Declare in another project. In this case the headers and the cmake files are not needed, only the library" OFF)
1719

1820
# defines variables used in the dbc.pc.in
1921
include(GNUInstallDirs)
@@ -30,7 +32,9 @@ if (NOT ${FastFloat_FOUND})
3032
GIT_REPOSITORY https://github.com/fastfloat/fast_float.git
3133
GIT_TAG 1ea4f27b2aeee2859a1354a3c24cff52a116cad1
3234
)
33-
FetchContent_MakeAvailable(FastFloat)
35+
# FetchContent_MakeAvailable(FastFloat)
36+
FetchContent_Populate(FastFloat)
37+
add_subdirectory(${fastfloat_SOURCE_DIR} ${fastfloat_BINARY_DIR} EXCLUDE_FROM_ALL)
3438
endif()
3539

3640
set(GCC_COMPILE_FLAGS "-Wextra -Wall -Wfloat-equal -Wundef -Wshadow \
@@ -92,18 +96,21 @@ install(TARGETS ${PROJECT_NAME}
9296
DESTINATION ${CMAKE_INSTALL_LIBDIR})
9397

9498
# install headers
95-
if (${CMAKE_MINOR_VERSION} GREATER_EQUAL 23)
99+
if (${CMAKE_MINOR_VERSION} GREATER_EQUAL 23 AND NOT FETCH_CONTENT_INCLUSION)
96100
install(TARGETS ${PROJECT_NAME}
97101
FILE_SET HEADERS
98102
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/lib${PROJECT_NAME}
99103
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
100104
)
101-
else()
105+
elseif(NOT FETCH_CONTENT_INCLUSION)
102106
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/libdbc DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
103107
endif()
104108

105-
# Generate pkg-config file
106-
configure_file(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY)
107-
install(
108-
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
109-
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
109+
110+
if (NOT FETCH_CONTENT_INCLUSION)
111+
# Generate pkg-config file
112+
configure_file(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY)
113+
install(
114+
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
115+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
116+
endif()

include/libdbc/message.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ struct Message {
3131
void appendSignal(const Signal& signal);
3232
const std::vector<Signal> getSignals() const;
3333
uint32_t id() const;
34+
const std::string& name() const {
35+
return m_name;
36+
}
3437
void addValueDescription(const std::string& signal_name, const std::vector<Signal::SignalValueDescriptions>&);
3538

3639
virtual bool operator==(const Message& rhs) const;

include/libdbc/signal.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#ifndef __SIGNAL_HPP__
33
#define __SIGNAL_HPP__
44

5+
#include <cstdint>
56
#include <iostream>
67
#include <string>
78
#include <vector>

src/message.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,8 @@ Message::ParseSignalsStatus Message::parseSignals(const std::vector<uint8_t>& da
3434
uint32_t start_bit = 8 * (signal.start_bit / 8) + (7 - (signal.start_bit % 8)); // Calculation taken from python CAN
3535
v = data_big_endian << start_bit;
3636
v = v >> (len - signal.size);
37-
} else {
38-
const uint32_t shiftLeft = (len - (signal.size + signal.start_bit));
39-
v = data_little_endian << shiftLeft;
40-
v = v >> (shiftLeft + signal.start_bit);
41-
}
37+
} else
38+
v = data_little_endian >> signal.start_bit;
4239

4340
if (signal.is_signed && signal.size > 1) {
4441
switch (signal.size) {
@@ -54,11 +51,23 @@ Message::ParseSignalsStatus Message::parseSignals(const std::vector<uint8_t>& da
5451
case 64:
5552
values.push_back((int64_t)v * signal.factor + signal.offset);
5653
break;
57-
default:
58-
return ParseSignalsStatus::ErrorInvalidConversion;
54+
default: {
55+
// 2 complement -> decimal
56+
const int negative = (v & (1 << (signal.size - 1))) != 0;
57+
int64_t nativeInt;
58+
if (negative)
59+
nativeInt = v | ~((1 << signal.size) - 1); // invert all bits above signal.size
60+
else
61+
nativeInt = v & ((1 << signal.size) - 1); // masking
62+
values.push_back(nativeInt * signal.factor + signal.offset);
63+
break;
5964
}
60-
} else
65+
}
66+
} else {
67+
// use only the relevant bits
68+
v = v & ((1 << signal.size) - 1); // masking
6169
values.push_back(v * signal.factor + signal.offset);
70+
}
6271
}
6372
return ParseSignalsStatus::Success;
6473
}

test/test_dbc.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ TEST_CASE("Testing big endian, little endian") {
8080
parser.parse_file(filename);
8181

8282
REQUIRE(parser.get_messages().size() == 1);
83+
REQUIRE(parser.get_messages().at(0).name() == "MSG1");
8384
REQUIRE(parser.get_messages().at(0).getSignals().size() == 2);
8485
{
8586
const auto signal = parser.get_messages().at(0).getSignals().at(0);
@@ -104,6 +105,7 @@ TEST_CASE("Testing negative values") {
104105
parser.parse_file(filename);
105106

106107
REQUIRE(parser.get_messages().size() == 1);
108+
REQUIRE(parser.get_messages().at(0).name() == "MSG1");
107109
REQUIRE(parser.get_messages().at(0).getSignals().size() == 4);
108110

109111
SECTION("Evaluating first message") {
@@ -146,6 +148,7 @@ TEST_CASE("Special characters in unit") {
146148
parser.parse_file(filename);
147149

148150
REQUIRE(parser.get_messages().size() == 1);
151+
REQUIRE(parser.get_messages().at(0).name() == "MSG1");
149152
REQUIRE(parser.get_messages().at(0).getSignals().size() == 1);
150153
SECTION("Checking that signal with special characters as unit is parsed correctly") {
151154
const auto signal = parser.get_messages().at(0).getSignals().at(0);
@@ -165,6 +168,7 @@ VAL_ 234 State1 123 "Description 1" 0 "Description 2" 90903489 "Big value and sp
165168
parser.parse_file(filename);
166169

167170
REQUIRE(parser.get_messages().size() == 1);
171+
REQUIRE(parser.get_messages().at(0).name() == "MSG1");
168172
REQUIRE(parser.get_messages().at(0).getSignals().size() == 2);
169173

170174
REQUIRE(parser.get_messages().at(0).getSignals().at(0).svDescriptions.size() == 3);
@@ -194,6 +198,7 @@ VAL_ 3221225472 State1 123 "Description 1" 0 "Description 2" 4000000000 "Big val
194198
parser.parse_file(filename);
195199

196200
REQUIRE(parser.get_messages().size() == 1);
201+
REQUIRE(parser.get_messages().at(0).name() == "MSG1");
197202
REQUIRE(parser.get_messages().at(0).getSignals().size() == 2);
198203

199204
REQUIRE(parser.get_messages().at(0).getSignals().at(0).svDescriptions.size() == 3);
@@ -217,7 +222,7 @@ TEST_CASE("Signal Value Multiple VAL_") {
217222
create_tmp_dbc_with(filename, R"(BO_ 3221225472 MSG1: 8 Vector__XXX
218223
SG_ State1 : 0|8@1+ (1,0) [0|200] "Km/h" DEVICE1,DEVICE2,DEVICE3
219224
SG_ State2 : 0|8@1+ (1,0) [0|204] "" DEVICE1,DEVICE2,DEVICE3"
220-
BO_ 123 MSG1: 8 Vector__XXX
225+
BO_ 123 MSG2: 8 Vector__XXX
221226
SG_ State1 : 0|8@1+ (1,0) [0|200] "Km/h" DEVICE1,DEVICE2,DEVICE3
222227
SG_ State2 : 0|8@1+ (1,0) [0|204] "" DEVICE1,DEVICE2,DEVICE3
223228
VAL_ 3221225472 State1 123 "Description 1" 0 "Description 2" ;
@@ -227,6 +232,9 @@ VAL_ 123 State1 123 "Description 3" 0 "Description 4" ;)");
227232
parser.parse_file(filename);
228233

229234
REQUIRE(parser.get_messages().size() == 2);
235+
REQUIRE(parser.get_messages().at(0).name() == "MSG1");
236+
REQUIRE(parser.get_messages().at(1).name() == "MSG2");
237+
230238
REQUIRE(parser.get_messages().at(0).getSignals().size() == 2);
231239

232240
REQUIRE(parser.get_messages().at(0).getSignals().at(0).svDescriptions.size() == 2);

test/test_parseMessage.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,41 @@ TEST_CASE("Parse Message big endian signed values") {
141141
REQUIRE(Catch::Approx(result_values.at(10)) == 3.5050);
142142
REQUIRE(Catch::Approx(result_values.at(11)) == 21.6);
143143
}
144+
145+
TEST_CASE("Parse Message with non byte aligned values") {
146+
const auto* filename = std::tmpnam(NULL);
147+
create_tmp_dbc_with(filename, R"(BO_ 403 INFORMATION: 8 Vector__XXX
148+
SG_ Voltage : 30|9@1+ (0.2,0) [0|102.2] "V" Vector__XXX
149+
SG_ Phase_Current : 20|10@1- (1,0) [-512|512] "A" Vector__XXX
150+
SG_ Iq_Current : 10|10@1- (1,0) [-512|512] "A" Vector__XXX
151+
SG_ Id_Current : 0|10@1- (1,0) [-512|512] "A" Vector__XXX)");
152+
153+
libdbc::DbcParser p;
154+
p.parse_file(filename);
155+
156+
std::vector<uint8_t> data{131, 51, 33, 9, 33, 0, 0, 0};
157+
std::vector<double> result_values;
158+
REQUIRE(p.parseMessage(403, data, result_values) == libdbc::Message::ParseSignalsStatus::Success);
159+
REQUIRE(result_values.size() == 4);
160+
REQUIRE(Catch::Approx(result_values.at(0)) == 26.4);
161+
REQUIRE(Catch::Approx(result_values.at(1)) == 146);
162+
REQUIRE(Catch::Approx(result_values.at(2)) == 76);
163+
REQUIRE(Catch::Approx(result_values.at(3)) == -125);
164+
}
165+
166+
TEST_CASE("Parse Message data length < 8 unsigned") {
167+
const auto* filename = std::tmpnam(NULL);
168+
create_tmp_dbc_with(filename, R"(BO_ 234 MSG1: 8 Vector__XXX
169+
SG_ Msg1Sig1 : 7|8@0+ (1,0) [-3276.8|-3276.7] "C" Vector__XXX
170+
SG_ Msg1Sig2 : 15|8@0+ (1,0) [-3276.8|-3276.7] "km/h" Vector__XXX)");
171+
172+
libdbc::DbcParser p;
173+
p.parse_file(filename);
174+
175+
std::vector<uint8_t> data{0x1, 0x2};
176+
std::vector<double> result_values;
177+
REQUIRE(p.parseMessage(234, data, result_values) == libdbc::Message::ParseSignalsStatus::Success);
178+
REQUIRE(result_values.size() == 2);
179+
REQUIRE(Catch::Approx(result_values.at(0)) == 0x1);
180+
REQUIRE(Catch::Approx(result_values.at(1)) == 0x2);
181+
}

0 commit comments

Comments
 (0)