OnixS C++ FIX Engine  4.10.1
API Documentation
Pretty Print Sample

This sample demonstrates the right way to iterate over all fields in a Message object and print them.

Source code:

#include <fstream>
#include <sstream>
#include <algorithm>
#include "../../Common/Helpers.h"
#include "../../Common/Settings.h"
using namespace Settings;
namespace {
static const std::string MessageLevelIndent = " ";
class MsgPrintFunctorBase
{
protected:
std::string messageLevel_;
int groupInstanceNumber_;
explicit MsgPrintFunctorBase(const std::string & messageLevel = "") : messageLevel_(messageLevel), groupInstanceNumber_(0) {}
void printField(Tag tag, const StringRef & tagValue)
{
std::clog << messageLevel_ << tag << "=" << tagValue << std::endl;
}
void beginGroup(Tag groupTag, const StringRef & groupTagValue)
{
std::clog << messageLevel_ << groupTag << "=> Group of " << groupTagValue << " item(s)" << std::endl;
messageLevel_.append(MessageLevelIndent);
}
void endGroup()
{
std::clog << messageLevel_ << "<= End of group" << std::endl;
messageLevel_.erase(messageLevel_.size() - MessageLevelIndent.size());
}
void beginGroupInstance()
{
std::ostringstream oss;
oss << groupInstanceNumber_++ << ": ";
messageLevel_.append(oss.str());
}
void endGroupInstance()
{
std::ostringstream oss;
oss << groupInstanceNumber_ << ": ";
messageLevel_.erase(messageLevel_.size() - oss.str().size());
}
};
class MsgPrintFunctor : private MsgPrintFunctorBase
{
public:
explicit MsgPrintFunctor(const std::string & messageLevel = "") : MsgPrintFunctorBase(messageLevel) {}
void operator()(const Field & field)
{
Group group;
if(field.value.toGroup(group))
{
beginGroup(field.tag, field.value.toStringRef());
std::for_each(group.begin(), group.end(), MsgPrintFunctor(messageLevel_));
endGroup();
}
else
printField(field.tag, field.value.toStringRef());
}
void operator()(const GroupInstance & instance)
{
beginGroupInstance();
std::for_each(instance.begin(), instance.end(), MsgPrintFunctor(messageLevel_));
endGroupInstance();
}
};
typedef std::vector<Tag> GroupTags;
class FlatMsgPrintFunctor : private MsgPrintFunctorBase
{
const FlatMessage * msg_;
GroupTags groupTags_;
public:
FlatMsgPrintFunctor(const FlatMessage * msg, const GroupTags & groupTags = GroupTags(), const std::string & messageLevel = "") : MsgPrintFunctorBase(messageLevel),
msg_(msg), groupTags_(groupTags){}
void operator()(const FlatField & field)
{
if(field.tag == Tags::NoRelatedSym)
{
beginGroup(field.tag, field.value);
FlatGroup group = msg_->getGroup(msg_->getFlatFieldRef(field.value));
GroupTags groupTags(1, Tags::Symbol);
std::for_each(group.begin(), group.end(), FlatMsgPrintFunctor(msg_, groupTags, messageLevel_));
endGroup();
}
else if(std::find(groupTags_.begin(), groupTags_.end(), field.tag) == groupTags_.end())
printField(field.tag, field.value);
}
void operator()(const FlatGroupInstance & instance)
{
beginGroupInstance();
for(GroupTags::const_iterator iter = groupTags_.begin(); iter != groupTags_.end(); ++iter)
{
FlatFieldRef ref = instance.find(*iter);
if(ref)
printField(*iter, instance[ref]);
}
FlatFieldRef groupRef = instance.find(Tags::NoLegs);
if(groupRef)
{
FlatGroup group = instance.getGroup(groupRef);
beginGroup(Tags::NoLegs, group.groupFieldValue());
GroupTags groupTags;
groupTags.push_back(Tags::LegSymbol);
groupTags.push_back(Tags::LegMaturityDate);
groupTags.push_back(Tags::LegStrikePrice);
groupTags.push_back(Tags::LegCurrency);
std::for_each(group.begin(), group.end(), FlatMsgPrintFunctor(msg_, groupTags, messageLevel_));
endGroup();
}
endGroupInstance();
}
};
}
int main()
{
std::clog << "Pretty print sample." << std::endl << std::endl;
try
{
EngineSettings settings;
settings.licenseStore(LicenseStore)
.listenPort(-1);
Engine::init(settings);
std::ifstream msgFile("message.fix");
std::string rawMsg((std::istreambuf_iterator<char> (msgFile)), std::istreambuf_iterator<char>());
Message msg;
Message::parse(rawMsg.c_str(), rawMsg.size(), MessageParsingFlag::Strict, msg);
std::clog << "Begin of Message:" << std::endl << std::endl;
std::for_each(msg.begin(), msg.end(), MsgPrintFunctor());
std::clog << std::endl << "End of Message" << std::endl << std::endl;
FlatMessage flatMsg(rawMsg.c_str(), rawMsg.size());
GroupTags groupTags;
groupTags.push_back(Tags::NoLegs);
groupTags.push_back(Tags::Symbol);
groupTags.push_back(Tags::LegSymbol);
groupTags.push_back(Tags::LegMaturityDate);
groupTags.push_back(Tags::LegStrikePrice);
groupTags.push_back(Tags::LegCurrency);
std::clog << "Begin of FlatMessage:" << std::endl << std::endl;
std::for_each(flatMsg.begin(), flatMsg.end(), FlatMsgPrintFunctor(&flatMsg, groupTags));
std::clog << std::endl << "End of FlatMessage" << std::endl;
Engine::shutdown();
}
catch(const std::exception & ex)
{
processSampleException(ex.what());
return 1;
}
return 0;
}