|
-
April 12th, 2013, 02:50 AM
#7
Re: "Creating variable" on runtime? - message decoding
 Originally Posted by HellMaster22
Thanks for your reply, superbonzo, but your code snippet is not applicable.
sorry, so, by "project dependant" you mean that the data structure itself is choosen at runtime, not just the id mapping, don't you ?
if yes, then, as suggested by Paul, you just need to define the proper abtraction for your data layout, which depends on the generality of the data structures you want to support. If they're just POD bitfields as it seems, then assuming a LIN file has the structure shown in your post ( sorry, I don't know VECTOR ) you could write something like:
Code:
// #include ... MSG_FRAME, BYTE, ...
#include <iostream>
#include <string>
#include <vector>
typedef BYTE Id;
struct BitField
{
std::size_t size; // in bit
std::string name;
};
class Frame
{
public:
Id GetId() const { return id_; }
friend std::istream& operator>>( std::istream& is, Frame& frame )
{
char d; // delimiter dummy
// parse header
is >> name_ >> d >> id_ >> d >> size_; // ignoring the '(...)' comments
is >> d; /// '{'
// parse bit fields
BitField field;
while( is >> field.name >> c >> field.size )
{
fields_.push_back( field );
}
// parse foot
is >> d; /// '}'
return is;
}
class View
{
public:
View( Frame const& frame, MSG_FRAME const& msg )
: frame_( frame ), msg_( msg ) {}
friend std::ostream& operator<<( std::ostream& os, View const& view )
{
assert( view.frame_.id_ == view.msg_.ID );
os << view.frame_.name_ // << .. put whatever info you like: size, id etc ...
<< std::endl;
// then the single fields
for( BitField const& field: view.frame_.fields_ )
{
os << field.name << " = " << // perform some bit twiddling to extract the field value from view.msg_.data
<< std::endl;
}
return os;
}
private:
Frame const& frame_;
MSG_FRAME const& msg_;
};
private:
Id id_;
std::size_t size_; // in bytes
std::string name_;
std::vector<BitField> fields_;
};
Frame::View MakeView( Frame const& frame, MSG_FRAME const& msg )
{
return Frame::View( frame, msg );
}
int main()
{
std::unordered_map<Id,Frame> message_map;
{
// populate the message map
std::ifstream message_file( /*... your 'external' file ... */ );
// skip the first "MessageFrames {" line
message_file.ignore(std::numeric_limits<std::streamsize>::max(), '\n')
// then go
Frame running_frame;
while( message_file >> running_frame )
{
message_map[ running_frame.GetId() ] = running_frame;
}
}
// pump messages
MSG_FRAME msg = /* some message source */;
std::cout << MakeView( message_map[ msg.ID ], msg );
}
BTW, note that due to the use of <iostream>, approaches like this result quite flexible, especially if combined with other iostream-aware libraries ( take a look at boost for example ) ...
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|