Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sequence length #145

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/mfast/ext_ref.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "decimal_ref.h"
#include "nested_message_ref.h"

#include <type_traits>

namespace mfast {
template <int V> struct fast_operator_tag : std::integral_constant<int, V> {};

Expand Down Expand Up @@ -147,6 +149,13 @@ class ext_cref<sequence_cref, LengthExtRef, ElementExtRef> {
explicit ext_cref(const field_cref &other) : base_(other) {}
cref_type get() const { return base_; }
length_type get_length(value_storage &storage) const {
if (std::is_same<typename LengthExtRef::operator_category, constant_operator_tag>::value)
storage = base_.instruction()->length_instruction()->initial_value();
else if (std::is_same<typename LengthExtRef::operator_category, copy_operator_tag>::value)
storage = base_.instruction()->length_instruction()->prev_value();
else if (std::is_same<typename LengthExtRef::operator_category, default_operator_tag>::value)
storage = base_.instruction()->length_instruction()->initial_or_default_value();

uint32_mref length_mref(nullptr, &storage,
base_.instruction()->length_instruction());
length_mref.as(base_.size());
Expand Down Expand Up @@ -333,6 +342,13 @@ class ext_mref<sequence_mref, LengthExtRef, ElementExtRef> {
cref_type get() const { return base_; }
is_optional_type optional() const { return is_optional_type(); }
length_type set_length(value_storage &storage) const {
if (std::is_same<typename LengthExtRef::operator_category, constant_operator_tag>::value)
storage = base_.instruction()->length_instruction()->initial_value();
else if (std::is_same<typename LengthExtRef::operator_category, copy_operator_tag>::value)
storage = base_.instruction()->length_instruction()->prev_value();
else if (std::is_same<typename LengthExtRef::operator_category, default_operator_tag>::value)
storage = base_.instruction()->length_instruction()->initial_or_default_value();

field_mref_base length_mref(nullptr, &storage,
base_.instruction()->length_instruction());
return length_type(length_mref);
Expand Down
4 changes: 4 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ FASTTYPEGEN_TARGET(simple_types10 simple10.xml)
FASTTYPEGEN_TARGET(simple_types11 simple11.xml)
FASTTYPEGEN_TARGET(simple_types12 simple12.xml)
FASTTYPEGEN_TARGET(simple_types13 simple13.xml)
FASTTYPEGEN_TARGET(simple_types14 simple14.xml)


FASTTYPEGEN_TARGET(test_types1 test1.xml test2.xml)
Expand Down Expand Up @@ -64,13 +65,16 @@ add_executable (mfast_test
${FASTTYPEGEN_simple_types11_OUTPUTS}
${FASTTYPEGEN_simple_types12_OUTPUTS}
${FASTTYPEGEN_simple_types13_OUTPUTS}
${FASTTYPEGEN_simple_types14_OUTPUTS}
fast_type_gen_test.cpp
dictionary_builder_test.cpp
json_test.cpp
int_vector_test.cpp
composite_type_test.cpp
aggregate_view_test.cpp
simple_coder_test.cpp
sequence_encoder_decoder_v2.cpp
sequence_encoder_decoder_v2.cpp
scp_reset_test.cpp
template_repo_base.cpp
message_pmap_test.cpp
Expand Down
133 changes: 133 additions & 0 deletions tests/sequence_encoder_decoder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#include "catch.hpp"
#include <mfast.h>

#include "fast_test_coding_case.hpp"
#include "byte_stream.h"

#include "simple14.h"

using namespace test::coding;

TEST_CASE("sequence optional copy operator by length encoder/decoder","[sequence_copy_operator_length_encoder_decoder]")
{
fast_test_coding_case<simple14::templates_description> test_case;
simple14::Test_1 test_1;
simple14::Test_1_mref test_1_mref = test_1.mref();
auto sequence_1_mref = test_1_mref.set_sequence_1();
sequence_1_mref.resize(1);

auto element_sequence = sequence_1_mref.front();
element_sequence.set_field_1_2().as(50);

test_1_mref.set_field_1_3().as(10);

REQUIRE(test_case.encoding(test_1.cref(),"\xE0\x81\x82\xC0\xB3\x8B",true));
REQUIRE(test_case.decoding("\xE0\x81\x82\xC0\xB3\x8B",test_1.cref(),true));
}

TEST_CASE("sequence optional constant operator by length encoder/decoder","[sequence_constant_operator_length_encoder_decoder]")
{
fast_test_coding_case<simple14::templates_description> test_case;
simple14::Test_2 test_2;
simple14::Test_2 test_3;

{
simple14::Test_2_mref test_2_mref = test_2.mref();

auto sequence_2_mref = test_2_mref.set_sequence_2();
// First time hast to be initalized and the same value from the configuration xml
sequence_2_mref.resize(1);

auto element_sequence = sequence_2_mref.front();
element_sequence.set_field_2_2().as(50);

test_2_mref.set_field_2_3().as(10);

REQUIRE(test_case.encoding(test_2.cref(),"\xE0\x82\xC0\xB3\x8B",true));
REQUIRE(test_case.decoding("\xE0\x82\xC0\xB3\x8B",test_2.cref(),true));
}
{
simple14::Test_2_mref test_3_mref = test_3.mref();

auto sequence_3_mref = test_3_mref.set_sequence_2();
sequence_3_mref.resize(2);

{
auto element_sequence = sequence_3_mref.front();
element_sequence.set_field_2_2().as(50);
}

{
auto element_sequence = sequence_3_mref.back();
element_sequence.set_field_2_2().as(60);
}

test_3_mref.set_field_2_3().as(10);

REQUIRE(test_case.encoding(test_3.cref(),"\xA0\x80\xC0\xBD\x8B"));
}
}

TEST_CASE("sequence optional default operator by length encoder/decoder","[sequence_default_operator_length_encoder_decoder]")
{
fast_test_coding_case<simple14::templates_description> test_case;
simple14::Test_3 test_3;
simple14::Test_3 test_4;

{
simple14::Test_3_mref test_3_mref = test_3.mref();

auto sequence_3_mref = test_3_mref.set_sequence_3();
// First time hast to be initalized and the same value from the configuration xml
sequence_3_mref.resize(1);

auto element_sequence = sequence_3_mref.front();
element_sequence.set_field_3_2().as(50);

test_3_mref.set_field_3_3().as(10);

REQUIRE(test_case.encoding(test_3.cref(),"\xC0\x83\xC0\xB3\x8B",true));
REQUIRE(test_case.decoding("\xC0\x83\xC0\xB3\x8B",test_3.cref(),true));
}

{
simple14::Test_3_mref test_4_mref = test_4.mref();

auto sequence_4_mref = test_4_mref.set_sequence_3();
sequence_4_mref.resize(2);

{
auto element_sequence = sequence_4_mref.front();
element_sequence.set_field_3_2().as(50);
}

{
auto element_sequence = sequence_4_mref.front();
element_sequence.set_field_3_2().as(60);
}

test_4_mref.set_field_3_3().as(10);

REQUIRE(test_case.encoding(test_4.cref(),"\xA0\x83\xC0\xBD\xC0\x80\x8B"));
}
}

TEST_CASE("sequence optional none operator by length encoder/decoder","[sequence_default_none_length_encoder_decoder]")
{
fast_test_coding_case<simple14::templates_description> test_case;
simple14::Test_4 test_4;
simple14::Test_4_mref test_4_mref = test_4.mref();

auto sequence_4_mref = test_4_mref.set_sequence_4();
sequence_4_mref.resize(1);

auto element_sequence = sequence_4_mref.front();
element_sequence.set_field_4_2().as(50);

test_4_mref.set_field_4_3().as(10);

REQUIRE(test_case.encoding(test_4.cref(),"\xC0\x84\x82\xC0\xB3\x8B",true));
REQUIRE(test_case.decoding("\xC0\x84\x82\xC0\xB3\x8B",test_4.cref(),true));
}


133 changes: 133 additions & 0 deletions tests/sequence_encoder_decoder_v2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#include "catch.hpp"
#include <mfast.h>

#include "fast_test_coding_case_v2.hpp"
#include "byte_stream.h"

#include "simple14.h"

using namespace test::coding;

TEST_CASE("sequence optional copy operator by length encoder_V2/decoder_v2","[sequence_copy_operator_length_encoder_v2_decoder_v2]")
{
fast_test_coding_case_v2<simple14::templates_description> test_case;
simple14::Test_1 test_1;
simple14::Test_1_mref test_1_mref = test_1.mref();
auto sequence_1_mref = test_1_mref.set_sequence_1();
sequence_1_mref.resize(1);

auto element_sequence = sequence_1_mref.front();
element_sequence.set_field_1_2().as(50);

test_1_mref.set_field_1_3().as(10);

REQUIRE(test_case.encoding(test_1.cref(),"\xE0\x81\x82\xC0\xB3\x8B",true));
REQUIRE(test_case.decoding("\xE0\x81\x82\xC0\xB3\x8B",test_1.cref(),true));
}

TEST_CASE("sequence optional constant operator by length encoder_V2/decoder_v2","[sequence_constant_operator_length_encoder_v2_decoder_v2]")
{
fast_test_coding_case_v2<simple14::templates_description> test_case;
simple14::Test_2 test_2;
simple14::Test_2 test_3;

{
simple14::Test_2_mref test_2_mref = test_2.mref();

auto sequence_2_mref = test_2_mref.set_sequence_2();
// First time hast to be initalized and the same value from the configuration xml
sequence_2_mref.resize(1);

auto element_sequence = sequence_2_mref.front();
element_sequence.set_field_2_2().as(50);

test_2_mref.set_field_2_3().as(10);

REQUIRE(test_case.encoding(test_2.cref(),"\xE0\x82\xC0\xB3\x8B",true));
REQUIRE(test_case.decoding("\xE0\x82\xC0\xB3\x8B",test_2.cref(),true));
}
{
simple14::Test_2_mref test_3_mref = test_3.mref();

auto sequence_3_mref = test_3_mref.set_sequence_2();
sequence_3_mref.resize(2);

{
auto element_sequence = sequence_3_mref.front();
element_sequence.set_field_2_2().as(50);
}

{
auto element_sequence = sequence_3_mref.back();
element_sequence.set_field_2_2().as(60);
}

test_3_mref.set_field_2_3().as(10);

REQUIRE(test_case.encoding(test_3.cref(),"\xA0\x80\xC0\xBD\x8B"));
}
}

TEST_CASE("sequence optional default operator by length encoder_V2/decoder_v2","[sequence_default_operator_length_encoder_v2_decoder_v2]")
{
fast_test_coding_case_v2<simple14::templates_description> test_case;
simple14::Test_3 test_3;
simple14::Test_3 test_4;

{
simple14::Test_3_mref test_3_mref = test_3.mref();

auto sequence_3_mref = test_3_mref.set_sequence_3();
// First time hast to be initalized and the same value from the configuration xml
sequence_3_mref.resize(1);

auto element_sequence = sequence_3_mref.front();
element_sequence.set_field_3_2().as(50);

test_3_mref.set_field_3_3().as(10);

REQUIRE(test_case.encoding(test_3.cref(),"\xC0\x83\xC0\xB3\x8B",true));
REQUIRE(test_case.decoding("\xC0\x83\xC0\xB3\x8B",test_3.cref(),true));
}

{
simple14::Test_3_mref test_4_mref = test_4.mref();

auto sequence_4_mref = test_4_mref.set_sequence_3();
sequence_4_mref.resize(2);

{
auto element_sequence = sequence_4_mref.front();
element_sequence.set_field_3_2().as(50);
}

{
auto element_sequence = sequence_4_mref.front();
element_sequence.set_field_3_2().as(60);
}

test_4_mref.set_field_3_3().as(10);

REQUIRE(test_case.encoding(test_4.cref(),"\xA0\x83\xC0\xBD\xC0\x80\x8B"));
}

// REQUIRE(test_case.decoding("\x80\x80\x8B", test_3.cref()));
}

TEST_CASE("sequence optional none operator by length encoder_V2/decoder_v2","[sequence_default_none_length_encoder_v2_decoder_v2]")
{
fast_test_coding_case_v2<simple14::templates_description> test_case;
simple14::Test_4 test_4;
simple14::Test_4_mref test_4_mref = test_4.mref();

auto sequence_4_mref = test_4_mref.set_sequence_4();
sequence_4_mref.resize(1);

auto element_sequence = sequence_4_mref.front();
element_sequence.set_field_4_2().as(50);

test_4_mref.set_field_4_3().as(10);

REQUIRE(test_case.encoding(test_4.cref(),"\xC0\x84\x82\xC0\xB3\x8B",true));
REQUIRE(test_case.decoding("\xC0\x84\x82\xC0\xB3\x8B",test_4.cref(),true));
}
31 changes: 31 additions & 0 deletions tests/simple14.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version=\" 1.0 \"?>
<templates xmlns="http://www.fixprotocol.org/ns/fast/td/1.1">
<template name="Test_1" id="1">
<sequence name="sequence_1" presence="optional">
<length name="field_1_1" id="12"><copy/></length>
<uInt32 name="field_1_2" id="13" presence="optional"><copy/></uInt32>
</sequence>
<uInt32 name="field_1_3" id="14" presence="optional"></uInt32>
</template>
<template name="Test_2" id="2">
<sequence name="sequence_2" presence="optional">
<length name="field_2_1" id="21"><constant value="1"/></length>
<uInt32 name="field_2_2" id="22" presence="optional"><copy/></uInt32>
</sequence>
<uInt32 name="field_2_3" id="23" presence="optional"></uInt32>
</template>
<template name="Test_3" id="3">
<sequence name="sequence_3" presence="optional">
<length name="field_3_1" id="31"><default value="1"/></length>
<uInt32 name="field_3_2" id="32" presence="optional"><copy/></uInt32>
</sequence>
<uInt32 name="field_3_3" id="33" presence="optional"></uInt32>
</template>
<template name="Test_4" id="4">
<sequence name="sequence_4" presence="optional">
<length name="field_4_1" id="41"></length>
<uInt32 name="field_4_2" id="42" presence="optional"><copy/></uInt32>
</sequence>
<uInt32 name="field_4_3" id="43" presence="optional"></uInt32>
</template>
</templates>