cjustas
asked on
C++ structure log out
Dear Experts,
I have to write plugin (.dll) that acts on specific hooks (events). When the hook is called, it passes variable of specific structure. it Looks something like this:
I have one method (in same CProc class) that takes structure, formats it to string and returns it with prefix of "ADDED" or "DELETED" to ExtLogger. Another method takes new and old structure and compares their members, if they members are different it puts it on the string. This way I get only what was changed on them. Now I'm doing it in most simplest way, which I don't like and I want to change it.
This is what I have as methods for formating:
Structure is much bigger and have different type for members so its even more complex.
Problem that I have is that output is bind to implementation, what I would like to have something like MODEL VIEW approach where "rendering" is taken out of the data it self.
Right now I have hard coded the way data looks, and if I need to change for example to CSV or JSON format, i have to go into each of the hard coded string and reformat it. I wonder what would be the ideal solution for outputting complex structures without having such closed for modification approach. Thank you.
P.S. please ignore sintax mistakes, as I tried to do only pseudo code, real source code compiles and works well, I just need to have better architecture for this problem.
I have to write plugin (.dll) that acts on specific hooks (events). When the hook is called, it passes variable of specific structure. it Looks something like this:
int CProc::SymbolsAdd(const StructSymb *symbol) {
ExtLogger.Out("SYMBOL ADDED %s", SymbolToStr(symbol).c_str());
}
int CProc::SymbolsUpdate(const StructSymb *newsymbol, const StructSymb *oldsymbol) {
ExtLogger.Out("SYMBOL CHANGED %s", SymbolChangesToStr(newsymbol, oldsymbol).c_str());
}
int CProc::SymbolsDelete(const StructSymb *symbol) {
ExtLogger.Out("SYMBOL DELETED %s", SymbolToStr(symbol).c_str());
}
struct StructSymb
{
char symbol[12];
int type;
int count;
int count_original;
int profit_mode;
int logging;
...
};
I have one method (in same CProc class) that takes structure, formats it to string and returns it with prefix of "ADDED" or "DELETED" to ExtLogger. Another method takes new and old structure and compares their members, if they members are different it puts it on the string. This way I get only what was changed on them. Now I'm doing it in most simplest way, which I don't like and I want to change it.
This is what I have as methods for formating:
std::string CProc::SymbolToStr(const StructSymb *symbol)
{
std::string buffer;
std::stringstream ss;
ss << symbol->symbol << " [" << std::endl;
ss << "\tSymbol\t['" << symbol->type << "'; " << symbol->count << "; '" << symbol->description << "'; " << symbol->count_original << "; " << std::fixed << std::setprecision(1) << (double)100/symbol->mode << ";" << std::endl;
//end so on...
ss << std::endl;
buffer = ss.str();
return(buffer);
}
std::string CProc::SymbolChangesToStr(const StructSymb *newsymbol, const StructSymb *oldsymbol)
{
std::string buffer;
std::stringstream ss;
if(newsymbol->count != oldsymbol->count)
ss << "Count changed from [" << oldsymbol->count << ", " newsymbol->count << "];";
if(newsymbol->mode != oldsymbol->mode)
ss << "Mode changed from [" << oldsymbol->mode << ", " newsymbol->mode << "];";
//end so on...
ss << std::endl;
buffer = ss.str();
return(buffer);
}
Structure is much bigger and have different type for members so its even more complex.
Problem that I have is that output is bind to implementation, what I would like to have something like MODEL VIEW approach where "rendering" is taken out of the data it self.
Right now I have hard coded the way data looks, and if I need to change for example to CSV or JSON format, i have to go into each of the hard coded string and reformat it. I wonder what would be the ideal solution for outputting complex structures without having such closed for modification approach. Thank you.
P.S. please ignore sintax mistakes, as I tried to do only pseudo code, real source code compiles and works well, I just need to have better architecture for this problem.
The concept that you are after seems to be 'serialization' (http://en.wikipedia.org/wiki/Serialization). While C++ does not provide 'native' support for that concept the 'boost' libraries do, see http://www.boost.org/doc/libs/1_46_1/libs/serialization/doc/index.html and http://www.boost.org/doc/libs/1_46_1/libs/serialization/doc/tutorial.html
you could provide operator<< for each class/struct like
the operator would allow to output your objects to any stream (cout, files, string streams). you even could generate the output operator by means of macros in the cpp file like
the macros would resolve to an implementation of operator<< taking the given class/struct as argument.
Sara
struct StructSymb
{
char symbol[12];
int type;
int count;
int count_original;
int profit_mode;
int logging;
friend std::ostream & operator<<(std::ostream & os, const StructSymb & s)
{
os << "symbol[12]=" << s.symbol << " | "
<< "type=" << type << " | "
<< ...;
return os;
}
};
the operator would allow to output your objects to any stream (cout, files, string streams). you even could generate the output operator by means of macros in the cpp file like
BEGIN_STREAM_OPERATOR(StructSymb)
STREAM_MEMBER(symbol)
STREAM_MEMBER(type)
...
END_STREAM_OPERATOR
the macros would resolve to an implementation of operator<< taking the given class/struct as argument.
Sara
ASKER
Both cases are more or less okay, but it covers only straight print out. What about printing only differences between two structures?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
cjustas, i don't have any problem if you post your own way to go with the issue and accept that comment as the solution. but i don't want you to accept my comment with an average grade. A C grade is only appropriate if you don't get a serious answer to your questions, what is not the case here. i made some efforts to post a solution for your requirements. you either do honor these efforts with at least a B grade or you may accept another solution. thanks.
Sara
p.s. you can reopen the q. by means of the 'Request Attention' button below your initial post.
Sara
p.s. you can reopen the q. by means of the 'Request Attention' button below your initial post.