mFAST
mFAST copied to clipboard
`fast_encoder` & `fast_encoder_v2` gives different encoded result
Test template:
<?xml version="1.0" encoding="UTF-8"?>
<templates version="2.25" xmlns="http://www.fixprotocol.org/ns/template-definition">
<template id="1" name="TestMessage">
<string name="MessageType" id="1"><constant value="TestMsg"/></string>
<int32 name="DataStatus" id="2" presence="optional"><default/></int32>
<int32 name="TradeIndex" id="3"><increment/></int32>
<int32 name="TradeChannel" id="4"><copy/></int32>
</template>
</templates>
Test program:
#include <iostream>
#include <string>
#include <mfast.h>
#include <mfast/coder/fast_decoder.h>
#include <mfast/coder/fast_encoder.h>
#include <mfast/coder/fast_encoder_v2.h>
#include "template/test.h"
using std::cout;
using std::endl;
using std::string;
void decode_print(const string& name, char *buf, size_t len) {
const mfast::templates_description* descriptions[]{test::description()};
mfast::fast_decoder decoder;
decoder.include(descriptions);
cout << "--------------------------------" << endl;
cout << name << endl;
cout << "raw data [" << len << "] : ";
for (size_t i = 0; i < len; ++i) {
uint8_t c = buf[i];
printf("%02X ", c);
}
cout << endl;
const char* first = buf;
const char* last = first + len;
while (first != last) {
try {
mfast::message_cref msg = decoder.decode(first, last, true);
cout << msg.name() << endl;
test::TestMessage_cref cmsg = static_cast<test::TestMessage_cref>(msg);
cout << string(cmsg.get_MessageType().name()) << " : " << cmsg.get_MessageType().value() << endl;
cout << string(cmsg.get_DataStatus().name()) << " present: " << cmsg.get_DataStatus().present()
<< ", absent: " << cmsg.get_DataStatus().absent() << endl;
cout << string(cmsg.get_TradeIndex().name()) << " : " << cmsg.get_TradeIndex().value() << endl;
cout << string(cmsg.get_TradeChannel().name()) << " : " << cmsg.get_TradeChannel().value() << endl;
} catch (boost::exception& e) {
cout << "decode failed!" << endl;
break;
}
}
cout << "--------------------------------" << endl;
}
int main()
{
const mfast::templates_description* descriptions[]{test::description()};
mfast::fast_encoder encoder;
mfast::fast_encoder_v2 encoder_v2(test::description());
encoder.include(descriptions);
char* buf1 = (char*)::malloc(1024);
char* buf2 = (char*)::malloc(1024);
test::TestMessage msg;
test::TestMessage_mref rmsg = msg.ref();
rmsg.set_TradeIndex().as(123);
rmsg.set_TradeChannel().as(456);
size_t l1 = encoder.encode(msg.cref(), buf1, 1024, true);
size_t l2 = encoder_v2.encode(msg.cref(), buf2, 1024, true);
decode_print("fast_encoder", buf1, l1);
decode_print("fast_encoder_v2", buf2, l2);
::free(buf1);
::free(buf2);
return 0;
}
Running result:
--------------------------------
fast_encoder
raw data [5] : B0 00 FB 03 C8
decode failed!
--------------------------------
--------------------------------
fast_encoder_v2
raw data [5] : 98 00 FB 03 C8
TestMessage
MessageType : TestMsg
DataStatus present: 0, absent: 1
TradeIndex : 123
TradeChannel : 456
--------------------------------
The encoded data stream is different, and fast_encoder
gives the wrong result.
It seems fast_encoder
do not handle optional field correctly.