OnixS C++ FIX Engine 2.79.1.0
Encoding and Decoding Data using FAST

FAST (FIX Adapted for Streaming) is a binary encoding method for message-oriented data streams.

FAST-related classes can be found in the OnixS::FIX::FAST namespace.

Encoding FIX Messages

To encode a FIX message into a FAST stream the OnixS::FIX::FAST::Encoder class is used.

using OnixS::FIX;
using OnixS::FIX::FAST;

string xmlFastTemplate = readTextFile("UdpFastTemplate.xml");

const bool encodeEachMessageIndependently = true;

Encoder encoder(xmlFastTemplate, sourceFixMessage.getVersion(), encodeEachMessageIndependently);

const int fastTemplateID = 36;

const size_t bufferSize = 1024;
char fastStreamChunk[bufferSize];

size_t chunkSize = encoder.encode(sourceFixMessage, fastTemplateID, fastStreamChunk, bufferSize);

Decoding FIX Messages

To decode a part of a FAST stream back into a FIX message the OnixS::FIX::FAST::Decoder class is used.

#include <assert.h>
#include <fstream>
#include <iostream>
#include <iterator>
#include <OnixS/FIXEngine.h>

using namespace OnixS::FIX;
using namespace std;

void fastDecoding()
{       
        EngineSettings settings;
        settings.listenPort(-1);
        settings.dialect("dialects/FixDialect_FDMM.xml");

        Engine::init(settings);

        ifstream fastTemplatesStream("templates/FastTemplates_FDMM.xml");
        assert(fastTemplatesStream);

        const string xmlFastTemplates((istreambuf_iterator<char>(fastTemplatesStream)), istreambuf_iterator<char>());
        assert(! xmlFastTemplates.empty());     

        Dialect dialect("FDMM");
        const bool decodeEachMessageIndependently = true;

        FAST::Decoder decoder(xmlFastTemplates, dialect, decodeEachMessageIndependently);       

        ifstream dataStream("data/fastChunk_FDMM.bin", ios_base::in | ios_base::binary);
        assert(dataStream);

        const string binaryChunk((istreambuf_iterator<char>(dataStream)), istreambuf_iterator<char>());
        assert(! binaryChunk.empty());          

        const Message& message = decoder.decode(binaryChunk.data(), binaryChunk.size());

        clog << "Decoded: " << message << endl;         

        Engine::shutdown();
}

Decoding multiple FIX Messages from the same binary chunk.

To decode multiple FIX Messages from the same binary chunk the OnixS::FIX::FAST::Decoder::tryDecode method is used.

Note:
Quite often it is needed to reset the Decoder state (using the OnixS::FIX::FAST::Decoder::reset method) before decoding a new FAST binary chunk.
#include <assert.h>
#include <fstream>
#include <iostream>
#include <iterator>
#include <OnixS/FIXEngine.h>

using namespace OnixS::FIX;
using namespace std;

void fastDecodeMultipleMessagesFromSameBinaryChunk()
{       
        EngineSettings settings;
        settings.listenPort(-1);
        settings.dialect("dialects/FixDialect_FDMM.xml");

        Engine::init(settings);

        ifstream fastTemplatesStream("templates/FastTemplates_FDMM.xml");
        assert(fastTemplatesStream);

        const string xmlFastTemplates((istreambuf_iterator<char>(fastTemplatesStream)), istreambuf_iterator<char>());
        assert(! xmlFastTemplates.empty());     

        Dialect dialect("FDMM");
        const bool decodeEachMessageIndependently = false;

        FAST::Decoder decoder(xmlFastTemplates, dialect, decodeEachMessageIndependently);       

        ifstream dataStream("data/fastChunk_FDMM.bin", ios_base::in | ios_base::binary);
        assert(dataStream);

        const string binaryChunk((istreambuf_iterator<char>(dataStream)), istreambuf_iterator<char>());
        assert(! binaryChunk.empty());          

        size_t offset = 0;
        size_t count = binaryChunk.length();
        const Message* message = 0;
        size_t numberOfDecodedBytes = 0;

        decoder.reset(); // to make sure that we start the FAST decoding from scratch.

        while(decoder.tryDecode(binaryChunk.data(), offset, count, &message, &numberOfDecodedBytes))
        {
                clog << "Decoded " << numberOfDecodedBytes << " bytes: " << *message << endl;
                offset += numberOfDecodedBytes;
                count -= numberOfDecodedBytes;
        }

        Engine::shutdown();
}