Skip to content

fast_encoder & fast_encoder_v2 gives different encoded result #126

@g199209

Description

@g199209

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions