Skip to content

Commit fc12ff2

Browse files
committed
Added documentation for CANDatabase + parse from directly from string + work on the interface of CANDatabase
1 parent b427659 commit fc12ff2

File tree

6 files changed

+325
-108
lines changed

6 files changed

+325
-108
lines changed

include/CANDatabase.h

Lines changed: 103 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,128 @@
99
#include "CANFrame.h"
1010
#include "CANDatabaseException.h"
1111

12+
/**
13+
* @brief A CAN database object
14+
*
15+
* A CAN database is an object regrouping frames and their signals' descriptions.
16+
*
17+
* Public API:
18+
* - contains to check if a frame name/frame id is registered in the database
19+
* - at to get the frame associated with the given frame name/frame id
20+
* the same operations are available with operator[]
21+
* - addFrame and removeFrame to alter the database's content
22+
*
23+
* If the database was parsed from a file, the filename() method can be used to
24+
* retrieve the name of the source file.
25+
*/
1226
class CANDatabase {
1327
public:
28+
/**
29+
* @brief Parse a CANDatabase from the given source file.
30+
* @param filename Path to the file to parse
31+
* @throw CANDatabaseException if the parsing failed
32+
*/
1433
static CANDatabase fromFile(const std::string& filename);
1534

35+
/**
36+
* @brief Construct a CANDatabase object from a database described by src_string
37+
* @param src_string Source string to parse
38+
* @throw CANDatabaseException if the parsing failed
39+
*/
40+
static CANDatabase fromString(const std::string& src_string);
41+
1642
public:
43+
/**
44+
* @brief Creates a CANDatabase object with no source file
45+
*/
46+
CANDatabase() = default;
47+
48+
/**
49+
* @brief Creates a CANDatabase object that has been constructed from a file
50+
* @param filename Name of the source file
51+
*/
1752
CANDatabase(const std::string& filename);
1853

1954
public:
20-
std::weak_ptr<CANFrame> getFrameById(unsigned int idx) const;
21-
std::weak_ptr<CANFrame> getFrameByName(const std::string& name) const;
22-
std::vector<std::weak_ptr<CANFrame>> frames() const;
55+
/**
56+
* @brief Get the frame with the given frame name
57+
*/
58+
std::weak_ptr<CANFrame> at(unsigned int frame_name) const;
59+
60+
/**
61+
* @brief Get the frame with the given frame id
62+
*/
63+
std::weak_ptr<CANFrame> at(const std::string& frame_name) const;
64+
65+
/**
66+
* @brief Get the frame with the given frame id
67+
* @see getFrame
68+
*/
69+
std::weak_ptr<CANFrame> operator[](unsigned int frame_idx) const;
70+
71+
/**
72+
* @brief Get the frame with the given frame name
73+
*/
74+
std::weak_ptr<CANFrame> operator[](const std::string& frame_name) const;
2375

24-
bool hasFrame(unsigned int can_id) const;
25-
bool hasFrame(const std::string& name) const;
76+
/**
77+
* @return true if the CANDatabase contains a frame with the given frame id
78+
*/
79+
bool contains(unsigned int frame_id) const;
2680

81+
/**
82+
* @return true if the CANDatabase contains a frame with the given frame name
83+
*/
84+
bool contains(const std::string& frame_name) const;
85+
86+
/**
87+
* @return File name of the source file if the database was constructed from a file.
88+
* Otherwise, returns an empty string.
89+
*/
2790
const std::string& filename() const;
91+
92+
93+
/* Set of methods used to behave like a STL container.
94+
Very useful for range-based for loops. Inspired from std::map but
95+
some features are missing.
96+
97+
The iterators have a random order. */
98+
public:
99+
using container_type = std::map<unsigned int, std::shared_ptr<CANFrame>>;
100+
using str_container_type = std::map<std::string, std::shared_ptr<CANFrame>>;
101+
using iterator = container_type::iterator;
102+
using const_iterator = container_type::const_iterator;
103+
using reverse_iterator = container_type::reverse_iterator;
104+
using const_reverse_iterator = container_type::const_reverse_iterator;
105+
106+
iterator begin();
107+
const_iterator begin() const;
108+
const_iterator cbegin() const;
109+
110+
iterator end();
111+
const_iterator end() const;
112+
const_iterator cend() const;
113+
114+
reverse_iterator rbegin();
115+
const_reverse_iterator rbegin() const;
116+
const_reverse_iterator crbegin() const;
117+
118+
reverse_iterator rend();
119+
const_reverse_iterator rend() const;
120+
const_reverse_iterator crend() const;
121+
28122
std::size_t size() const;
29123

124+
void clear();
125+
30126
void addFrame(std::shared_ptr<CANFrame> frame);
31127
void removeFrame(unsigned int idx);
32128
void removeFrame(const std::string& name);
33129

34130
private:
35131
std::string filename_;
36-
std::map<std::string, std::shared_ptr<CANFrame>> strIndex_; // Index by frame name
37-
std::map<unsigned int, std::shared_ptr<CANFrame>> intIndex_; // Index by CAN ID
132+
str_container_type strIndex_; // Index by frame name
133+
container_type intIndex_; // Index by CAN ID
38134
};
39135

40136
#endif

include/DBCParser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
namespace DBCParser {
1010
CANDatabase fromTokenizer(const std::string& name,
1111
Tokenizer& tokenizer);
12+
13+
CANDatabase fromTokenizer(Tokenizer& tokenizer);
1214
};
1315

1416
#endif

include/Tokenizer.h

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,44 +8,56 @@
88

99
class Tokenizer {
1010
public:
11-
Tokenizer(const std::string& filename) :
12-
inputstream(filename), currentChar(0), currentToken(), started(false), eofReached(false), addLine(false),
13-
charCnt(0), lineCnt(0) {}
14-
15-
bool is_valid() const {
16-
return inputstream.is_open();
17-
}
18-
11+
Tokenizer();
12+
virtual ~Tokenizer() = default;
13+
1914
Token getNextToken();
2015
Token getCurrentToken() const;
16+
2117
void skipLine();
2218
void skipUntil(const std::string& token);
2319
void saveToken(const Token& token);
2420

2521
unsigned long long charCount() const;
2622
unsigned long long lineCount() const;
2723

28-
private:
24+
protected:
2925
char getNextChar();
30-
26+
char getCurrentChar() const;
27+
3128
private:
32-
bool isSeparator(char c) const;
33-
bool isEOF(char c) const;
34-
bool isDigit(char c) const;
35-
bool isSpace(char c) const;
36-
bool isIdentifierStart(char c) const;
37-
bool isIdentifierPart(char c) const;
29+
virtual char doGetNextChar() = 0;
3830

3931
private:
40-
std::ifstream inputstream;
4132
char currentChar;
4233
Token currentToken;
4334
std::vector<Token> tokenStack;
4435
bool started;
45-
bool eofReached;
46-
bool addLine;
36+
37+
protected:
4738
unsigned long long charCnt;
4839
unsigned long long lineCnt;
40+
bool addLine;
4941
};
5042

43+
class FileTokenizer : public Tokenizer {
44+
public:
45+
FileTokenizer(const std::string& filename);
46+
47+
virtual char doGetNextChar();
48+
49+
private:
50+
std::ifstream inputstream;
51+
52+
};
53+
54+
class StringTokenizer : public Tokenizer {
55+
public:
56+
StringTokenizer(const std::string& src_string);
57+
58+
virtual char doGetNextChar();
59+
60+
private:
61+
std::string src_str;
62+
};
5163
#endif

src/models/CANDatabase.cpp

Lines changed: 78 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,21 @@ std::size_t CANDatabase::size() const {
1515
}
1616

1717
CANDatabase CANDatabase::fromFile(const std::string& filename) {
18-
Tokenizer tokenizer(filename);
19-
20-
if(!tokenizer.is_valid()) {
18+
std::ifstream test_stream(filename);
19+
if (!test_stream.good()) {
2120
throw CANDatabaseException("Cannot find file " + filename);
2221
}
23-
22+
23+
FileTokenizer tokenizer(filename);
2424
return DBCParser::fromTokenizer(filename, tokenizer);
2525
}
2626

27-
std::weak_ptr<CANFrame> CANDatabase::getFrameByName(const std::string& name) const {
27+
CANDatabase CANDatabase::fromString(const std::string & src_string) {
28+
StringTokenizer tokenizer(src_string);
29+
return DBCParser::fromTokenizer(tokenizer);
30+
}
31+
32+
std::weak_ptr<CANFrame> CANDatabase::at(const std::string& name) const {
2833
std::weak_ptr<CANFrame> result;
2934

3035
auto ite = strIndex_.find(name);
@@ -34,7 +39,7 @@ std::weak_ptr<CANFrame> CANDatabase::getFrameByName(const std::string& name) con
3439
return result;
3540
}
3641

37-
std::weak_ptr<CANFrame> CANDatabase::getFrameById(unsigned int id) const {
42+
std::weak_ptr<CANFrame> CANDatabase::at(unsigned int id) const {
3843
std::weak_ptr<CANFrame> result;
3944

4045
auto ite = intIndex_.find(id);
@@ -44,16 +49,6 @@ std::weak_ptr<CANFrame> CANDatabase::getFrameById(unsigned int id) const {
4449
return result;
4550
}
4651

47-
std::vector<std::weak_ptr<CANFrame>> CANDatabase::frames() const {
48-
std::vector<std::weak_ptr<CANFrame>> result;
49-
result.reserve(intIndex_.size());
50-
51-
for(const auto& sigIte: intIndex_) {
52-
result.emplace_back(sigIte.second);
53-
}
54-
return result;
55-
}
56-
5752
void CANDatabase::addFrame(std::shared_ptr<CANFrame> frame) {
5853
if(strIndex_.find(frame->name()) != strIndex_.end()) {
5954
std::cout << "WARNING: Double declaration of a frame with name "
@@ -94,10 +89,75 @@ void CANDatabase::removeFrame(unsigned int can_id) {
9489
strIndex_.erase(strIndex_.find(strIdx));
9590
}
9691

97-
bool CANDatabase::hasFrame(unsigned int can_id) const {
92+
bool CANDatabase::contains(unsigned int can_id) const {
9893
return intIndex_.find(can_id) != intIndex_.end();
9994
}
10095

101-
bool CANDatabase::hasFrame(const std::string& name) const {
96+
bool CANDatabase::contains(const std::string& name) const {
10297
return strIndex_.find(name) != strIndex_.end();
10398
}
99+
100+
CANDatabase::iterator
101+
CANDatabase::begin() {
102+
return intIndex_.begin();
103+
}
104+
105+
CANDatabase::const_iterator
106+
CANDatabase::begin() const {
107+
return intIndex_.begin();
108+
}
109+
110+
CANDatabase::const_iterator
111+
CANDatabase::cbegin() const {
112+
return intIndex_.cbegin();
113+
}
114+
115+
CANDatabase::iterator
116+
CANDatabase::end() {
117+
return intIndex_.end();
118+
}
119+
120+
CANDatabase::const_iterator
121+
CANDatabase::end() const {
122+
return intIndex_.end();
123+
}
124+
125+
CANDatabase::const_iterator
126+
CANDatabase::cend() const {
127+
return intIndex_.cend();
128+
}
129+
130+
CANDatabase::reverse_iterator
131+
CANDatabase::rbegin() {
132+
return intIndex_.rbegin();
133+
}
134+
135+
CANDatabase::const_reverse_iterator
136+
CANDatabase::rbegin() const {
137+
return intIndex_.rbegin();
138+
}
139+
140+
CANDatabase::const_reverse_iterator
141+
CANDatabase::crbegin() const {
142+
return intIndex_.crbegin();
143+
}
144+
145+
CANDatabase::reverse_iterator
146+
CANDatabase::rend() {
147+
return intIndex_.rend();
148+
}
149+
150+
CANDatabase::const_reverse_iterator
151+
CANDatabase::rend() const {
152+
return intIndex_.rend();
153+
}
154+
155+
CANDatabase::const_reverse_iterator
156+
CANDatabase::crend() const {
157+
return intIndex_.crend();
158+
}
159+
160+
void CANDatabase::clear() {
161+
intIndex_.clear();
162+
strIndex_.clear();
163+
}

0 commit comments

Comments
 (0)