B2BITS FIX Antenna C++  2.27.1
FAST Codec Quick start

These chapters describe the creation of a simple application that shows how to use the FastCodec, step-by step with samples.

Follow these instructions to get it working:

Initialize FAST codec

Execute the following instruction to initialize the FastCodec.

// Initialize the FastCodec
Engine::FastCodec fastCodec("../../../engine.license");

In the call above you should specify a path to a license file. If the specified file doesn't exist or the license isn't valid, an exception will be thrown.

try
{
// Initialize the FastCodec
Engine::FastCodec fastCodec("../../../engine.license");
}
catch (const Utils::Exception& error)
{
cout << "ERROR: " << error.what() << endl;
}

Create new FAST coder

To create new instance of FastCoder, execute the following instruction.

// Create FastCoder
std::auto_ptr<Engine::FastCoder> fastCoder(
fastCodec.createFastCoder(
"additional.xml",
"templates.xml",

Create new FAST decoder

To create new instance of FastDecoder, execute the following instruction.

// Create FastDecoder
std::auto_ptr<Engine::FastDecoder> fastDecoder(
fastCodec.createFastDecoder(
"additional.xml",
"templates.xml",

Create new FIX message

To create new FIX message, execute the following instruction.

fixMessages[i] = fastCoder->newSkel("X");

The next step is to fill the message fields.

fixMessages[i]->set(FIXFields::ApplVerID, "9");
fixMessages[i]->set(FIXFields::SenderCompID, "MICEX");
fixMessages[i]->set(FIXFields::MsgSeqNum, i);
fixMessages[i]->set(FIXFields::NoMDEntries, 1);
Engine::FIXGroup* grp = fixMessages[i]->getGroup(FIXFields::NoMDEntries);
Engine::TagValue* entry = grp->getEntry(0);
{
char mdEntryId[2] = {0};
mdEntryId[0] = (char) i + '0';
entry->set(FIXFields::MDEntryID, mdEntryId);
char symbol[] = "symbol_";
symbol[sizeof(symbol) - 2] = (char) i + '0';
entry->set(FIXFields::Symbol, symbol);
entry->set(FIXFields::RptSeq, i + 10);
entry->set(FIXFields::MDEntryPx, Engine::Decimal(i * 10, i % 4));
entry->set(FIXFields::MDEntrySize, i * 12);
}

Encode

To encode the FIX message, execute the following instruction.

// Encode message
// Node: the specified buffer will be reused.
fastCoder->encode(fixMessages[i].get(), &buffer);

Decode

To decode the FAST message, execute the following instruction.

// Decode the fast message back to fix message
std::auto_ptr<Engine::FIXMessage> decodedFixMessage(fastDecoder->decode(buffer.getPtr(), buffer.getSize()));

Full sample

The sample below illustrates all above mentioned instructions combined in one application.

#include <iostream>
#include <B2BITS_FIXFields.h>
#include <B2BITS_FIXGroup.h>
#include <B2BITS_FastCodec.h>
namespace
{
// template id, used for encoding fix messages
const int TEMPLATE_ID = 4;
// count of fix messages that are encode/decoded in this example
const int COUNT_FIX_MESSAGES = 3;
}
void runSample(Engine::FastCodec& fastCodec)
{
// Create FastCoder
std::auto_ptr<Engine::FastCoder> fastCoder(
fastCodec.createFastCoder(
"additional.xml",
"templates.xml",
// Create FastDecoder
std::auto_ptr<Engine::FastDecoder> fastDecoder(
fastCodec.createFastDecoder(
"additional.xml",
"templates.xml",
std::auto_ptr<Engine::FIXMessage> fixMessages[COUNT_FIX_MESSAGES];
// Create several FIX messages
for (int i = 0; i < COUNT_FIX_MESSAGES; ++i)
{
fixMessages[i] = fastCoder->newSkel("X");
fixMessages[i]->set(FIXFields::ApplVerID, "9");
fixMessages[i]->set(FIXFields::SenderCompID, "MICEX");
fixMessages[i]->set(FIXFields::MsgSeqNum, i);
fixMessages[i]->set(FIXFields::NoMDEntries, 1);
Engine::FIXGroup* grp = fixMessages[i]->getGroup(FIXFields::NoMDEntries);
Engine::TagValue* entry = grp->getEntry(0);
{
char mdEntryId[2] = {0};
mdEntryId[0] = (char) i + '0';
entry->set(FIXFields::MDEntryID, mdEntryId);
char symbol[] = "symbol_";
symbol[sizeof(symbol) - 2] = (char) i + '0';
entry->set(FIXFields::Symbol, symbol);
entry->set(FIXFields::RptSeq, i + 10);
entry->set(FIXFields::MDEntryPx, Engine::Decimal(i * 10, i % 4));
entry->set(FIXFields::MDEntrySize, i * 12);
}
}
for (int i = 0; i < COUNT_FIX_MESSAGES; ++i)
{
// Print message
int size(0);
char const* raw = fixMessages[i]->toRaw(&size);
std::cout << "Sources message: " << Engine::AsciiString(raw, size) << std::endl;
try
{
// Check if the specified message can be encoded without errors using the specified template.
// This method silently returns a control if no errors detected; otherwise throws an exception with detailed information.
// Usually used for debugging purpose.
fastCoder->tryEncode(fixMessages[i].get(), TEMPLATE_ID);
}
catch (Utils::Exception const& error)
{
std::cerr << "TryEncode Error: " << error.what() << std::endl;
}
// Reset the fast coder dictionary (optional)
fastCoder->resetDictionary();
// Encode message
// Node: the specified buffer will be reused.
fastCoder->encode(fixMessages[i].get(), &buffer);
// Reset the fast decoder dictionary (optional)
fastDecoder->resetDictionary();
// Decode the fast message back to fix message
std::auto_ptr<Engine::FIXMessage> decodedFixMessage(fastDecoder->decode(buffer.getPtr(), buffer.getSize()));
// Print message
raw = decodedFixMessage->toRaw(&size);
std::cout << "Decoded message: " << Engine::AsciiString(raw, size) << std::endl;
}
}
int main()
{
try
{
// Initialize the FIX Antenna Engine
Engine::FixEngine::init("engine.properties");
// Rus the sample
runSample();
}
catch (Utils::Exception const& error)
{
std::cerr << "ERROR: " << error.what() << std::endl;
}
}