mFAST icon indicating copy to clipboard operation
mFAST copied to clipboard

Encoder can create invalid pm, unable to decode, dependent on element.count.

Open adamyg opened this issue 2 years ago • 0 comments

Dependent on the schema size, the resulting encoded pm is invalid; could be similar to #111 and #85. Note; Adding additional elements to Template2 has the correct result.

Example, mfasttest.xml:

<?xml version="1.0" encoding="UTF-8"?>
<templates xmlns="http://www.fixprotocol.org/ns/template-definition" 
                 templateNs="http://www.fixprotocol.org/ns/templates/sample"
                 ns="http://www.fixprotocol.org/ns/fix"> 
        <template name="Template1" id="100">
                <int32 name="Field1" id="10000"></int32>
        </template>
        <template name="Template2" id="200">
               <int32 name="Field1" id="10000"></int32>
               <int32 name="Extra01" id="10001" presence="optional"><default/></int32>
               <int32 name="Extra02" id="10002" presence="optional"><default/></int32>
               <int32 name="Extra03" id="10003" presence="optional"><default/></int32>
               <int32 name="Extra04" id="10004" presence="optional"><default/></int32>
               <int32 name="Extra05" id="10005" presence="optional"><default/></int32>
               <int32 name="Extra06" id="10006" presence="optional"><default/></int32>
               <int32 name="Extra07" id="10007" presence="optional"><default/></int32>
        </template>
</templates>

Code:

#include <string>
#include <iostream>

#include <mfast.h>
#include <mfast/malloc_allocator.h>
#include <mfast/coder/fast_encoder.h>
#include <mfast/coder/fast_encoder_v2.h>
#include <mfast/coder/fast_decoder.h>
#include <mfast/coder/fast_decoder_v2.h>

// fast_type_gen mfasttest.xml
#include "mfasttest.h"
#include "mfasttest.cpp"

// https://github.com/zmb3/hexdump
#include "hexdump.h" 

int main()
{
    char buffer[1024] = {0};
    size_t size;

    try
    {
       { // encode
         mfast::malloc_allocator allocator;
         mfast::fast_encoder_v2 encoder(&allocator, mfasttest::templates_description::instance());
         mfasttest::Template2 msg(&allocator);
         mfasttest::Template2_mref mref(msg.mref());
         
         mref.set_Field1().as(8193);
         size = encoder.encode(mref, buffer, sizeof(buffer), true);
         assert(size && size < szieof(buffer));        
      
         std::cout << "decoding, size=" << size << '\n';
         std::cout << Hexdump(buffer, size) << std::endl; 
       }

       { // decode
          mfast::malloc_allocator allocator;
          mfast::fast_decoder_v2<false/*ro*/> decoder(&allocator, mfasttest::templates_description::instance());
          const char *first = buffer, *last = buffer + size;
          
          const auto result = decoder.decode(first, last, true);
          const mfasttest::Template2_cref cref(result);          
          assert(cref.get_Field1().value() == 8193);
       }

    } catch (const boost::exception& e) {
       std::cout << "mfastestt: " << boost::diagnostic_information(e) << std::endl;
    } catch (const std::exception& e) {
       std::cout << "mfasttest: " << e.what() << std::endl;
    } catch (...){
       std::cout << "mfasttest: general exception" << std::endl;
    }
    return 0;
}

Output:

decoding, size=6
0x000000: 40 80 c8 00 40 81                                @...@.

mfasttest: /devl/mFAST-master/src/mfast/coder/decoder_v2/fast_decoder_core.h(664): Throw in function const mfast::message_mref& mfast::coder::fast_decoder_core<NumTokens>::decode_segment(mfast::fast_istreambuf&) [with unsigned int NumTokens = 0]
Dynamic exception type: boost::wrapexcept<mfast::fast_dynamic_error>
std::exception::what: std::exception
[mfast::tag_error_code*] = D9
[mfast::coder::tag_template_id*] = 72

adamyg avatar Feb 10 '23 05:02 adamyg