diff --git a/src/fast_type_gen/inl_gen.cpp b/src/fast_type_gen/inl_gen.cpp index 6fabeae5..c19f19d1 100644 --- a/src/fast_type_gen/inl_gen.cpp +++ b/src/fast_type_gen/inl_gen.cpp @@ -681,8 +681,16 @@ void inl_gen::visit(const mfast::sequence_field_instruction *inst, for (std::size_t i = 0; i < inst->subinstructions().size(); ++i) { const field_instruction *subinst = inst->subinstructions()[i]; - out_ << " visitor.visit(" << get_ext_cref_type(subinst) << " ((*this)[" - << i << "]) );\n"; + if (is_group_type(subinst) && subinst->optional()) + { + out_ << " {\n" + << " " << get_ext_cref_type(subinst) << " ext_cref_group((*this)[" << i << "]);\n" + << " ext_cref_group.set_group_present(this->field_storage(" << i << ")->is_present());\n" + << " visitor.visit(ext_cref_group);\n" + << " }\n"; + } + else + out_ << " visitor.visit(" << get_ext_cref_type(subinst) << " ((*this)[" << i << "]) );\n"; } out_ << "}\n\n"; diff --git a/src/mfast/coder/encoder/encoder_field_operator.cpp b/src/mfast/coder/encoder/encoder_field_operator.cpp index 230428e9..9150f711 100644 --- a/src/mfast/coder/encoder/encoder_field_operator.cpp +++ b/src/mfast/coder/encoder/encoder_field_operator.cpp @@ -548,6 +548,7 @@ class delta_operator : public encoder_field_operator, cref.exponent() - bv.of_decimal.exponent_; delta_storage.of_decimal.mantissa_ = cref.mantissa() - bv.of_decimal.mantissa_; + delta_storage.of_decimal.present_ = cref.present(); decimal_cref delta(&delta_storage, cref.instruction()); stream << delta; diff --git a/src/mfast/ext_ref.h b/src/mfast/ext_ref.h index 60bf81aa..cba11441 100644 --- a/src/mfast/ext_ref.h +++ b/src/mfast/ext_ref.h @@ -205,13 +205,13 @@ class ext_cref explicit ext_cref(const field_cref &base) : base_(base) {} explicit ext_cref(const aggregate_cref &base) : base_(base) {} cref_type get() const { return base_; } - bool present() const { return !this->optional() || group_present_; } + bool present() const { return group_present_; } void set_group_present(bool present) { group_present_ = present; } private: cref_type base_; - bool group_present_ = true; + bool group_present_ = this->optional()?false:true; }; template diff --git a/tests/encoder_decoder_test.cpp b/tests/encoder_decoder_test.cpp index 768b663d..15cdd535 100644 --- a/tests/encoder_decoder_test.cpp +++ b/tests/encoder_decoder_test.cpp @@ -280,3 +280,19 @@ TEST_CASE("sequence optional with constant length encoder/decoder","[optional_se REQUIRE(test_case.decoding("\xF0\x87\x82\xa0\x82\x82",test_7.cref(),true)); } } + +TEST_CASE("decimal optional encoder/decoder","[decimal_optional_encoder_decoder]") +{ + fast_test_coding_case test_case; + + SECTION("encode decimal value") + { + simple12::Test_8 test_8; + simple12::Test_8_mref test_8_mref = test_8.mref(); + test_8_mref.set_field_8_1().as(15, 1); + test_8_mref.set_field_8_2().as(20); + + REQUIRE(test_case.encoding(test_8.cref(),"\xE0\x88\x81\x8F\x94",true)); + REQUIRE(test_case.decoding("\xE0\x88\x81\x8F\x94",test_8.cref(),true)); + } +} \ No newline at end of file diff --git a/tests/encoder_decoder_test_v2.cpp b/tests/encoder_decoder_test_v2.cpp index 0aabce9d..08fe5625 100644 --- a/tests/encoder_decoder_test_v2.cpp +++ b/tests/encoder_decoder_test_v2.cpp @@ -281,3 +281,19 @@ TEST_CASE("sequence optional with constant length encoder_v2/decoder_v2","[optio REQUIRE(test_case.decoding("\xF0\x87\x82\xa0\x82\x82",test_7.cref(),true)); } } + +TEST_CASE("decimal optional encoder_v2/decoder_v2","[decimal_optional_encoder_v2/decoder_v2]") +{ + fast_test_coding_case_v2 test_case; + + SECTION("encode decimal value") + { + simple12::Test_8 test_8; + simple12::Test_8_mref test_8_mref = test_8.mref(); + test_8_mref.set_field_8_1().as(15, 1); + test_8_mref.set_field_8_2().as(20); + + REQUIRE(test_case.encoding(test_8.cref(),"\xE0\x88\x81\x8F\x94",true)); + REQUIRE(test_case.decoding("\xE0\x88\x81\x8F\x94",test_8.cref(),true)); + } +} diff --git a/tests/fast_test_coding_case_v2.hpp b/tests/fast_test_coding_case_v2.hpp index be06cf30..42dc0967 100644 --- a/tests/fast_test_coding_case_v2.hpp +++ b/tests/fast_test_coding_case_v2.hpp @@ -18,8 +18,7 @@ class fast_test_coding_case_v2 decoder_v2_(DESC::instance()) {} - bool - encoding(const mfast::message_cref& msg_ref, const byte_stream& result, bool reset=false) + bool encoding(const mfast::message_cref& msg_ref, const byte_stream& result, bool reset=false) { const int buffer_size = 128; char buffer[buffer_size]; @@ -32,8 +31,7 @@ class fast_test_coding_case_v2 return false; } - bool - decoding(const byte_stream& bytes, const mfast::message_cref& result, bool reset=false) + bool decoding(const byte_stream& bytes, const mfast::message_cref& result, bool reset=false) { const char* first = bytes.data(); mfast::message_cref msg = decoder_v2_.decode(first, first+bytes.size(), reset); diff --git a/tests/sequence_encoder_decoder.cpp b/tests/sequence_encoder_decoder.cpp index e2d1fb8c..67a54f89 100644 --- a/tests/sequence_encoder_decoder.cpp +++ b/tests/sequence_encoder_decoder.cpp @@ -237,3 +237,62 @@ TEST_CASE("group sequence inside sequence encoder/decoder","[group_sequence_insi REQUIRE(test_case.decoding("\xC0\x86\x81\xD0\xB2\x82\xB2",test_6.cref(),true)); } } + +TEST_CASE("sequence with optional group encoder/decoder","[sequence_optional_group_encoder_decoder]") +{ + fast_test_coding_case test_case; + + SECTION("group not present") + { + simple14::Test_7 test_7; + simple14::Test_7_mref test_7_mref = test_7.mref(); + + auto sequence_7_mref = test_7_mref.set_sequence_7(); + sequence_7_mref.resize(1); + + auto element_sequence = sequence_7_mref.front(); + element_sequence.set_field_7_3().as(50); + + REQUIRE(test_case.encoding(test_7.cref(),"\xC0\x87\x81\xC0\xB2",true)); + REQUIRE(test_case.decoding("\xC0\x87\x81\xC0\xB2",test_7.cref(),true)); + } + + SECTION("group present") + { + simple14::Test_7 test_7; + simple14::Test_7_mref test_7_mref = test_7.mref(); + + auto sequence_7_mref = test_7_mref.set_sequence_7(); + sequence_7_mref.resize(1); + + auto element_sequence = sequence_7_mref.front(); + element_sequence.set_field_7_3().as(50); + + auto group_7 = element_sequence.set_group_7(); + group_7.set_field_7_4().as(20); + + REQUIRE(test_case.encoding(test_7.cref(),"\xC0\x87\x81\xE0\xB2\x94",true)); + REQUIRE(test_case.decoding("\xC0\x87\x81\xE0\xB2\x94",test_7.cref(),true)); + } +} + +TEST_CASE("sequence with optional decimal encoder/decoder", "[sequence_with_optional_decimal_encoder_decoder]") +{ + fast_test_coding_case test_case; + + SECTION("decimal present") + { + simple14::Test_8 test_8; + simple14::Test_8_mref test_8_mref = test_8.mref(); + + auto sequence_8_mref = test_8_mref.set_sequence_8(); + sequence_8_mref.resize(1); + + auto element_sequence = sequence_8_mref.front(); + element_sequence.set_field_8_2().as(50); + element_sequence.set_field_8_3().as(10, 1); + + REQUIRE(test_case.encoding(test_8.cref(),"\xC0\x88\x81\xC0\xB2\x82\x8A",true)); + REQUIRE(test_case.decoding("\xC0\x88\x81\xC0\xB2\x82\x8A",test_8.cref(),true)); + } +} diff --git a/tests/sequence_encoder_decoder_v2.cpp b/tests/sequence_encoder_decoder_v2.cpp index bbf05cdd..0972e1d0 100644 --- a/tests/sequence_encoder_decoder_v2.cpp +++ b/tests/sequence_encoder_decoder_v2.cpp @@ -239,3 +239,62 @@ TEST_CASE("group sequence inside sequence encoder_V2/decoder_v2","[group_sequenc REQUIRE(test_case.decoding("\xC0\x86\x81\xD0\xB2\x82\xB2",test_6.cref(),true)); } } + +TEST_CASE("sequence with optional group encoder_V2/decoder_v2","[sequence_optional_group_encoder_v2_decoder_v2]") +{ + fast_test_coding_case_v2 test_case; + + SECTION("group not present") + { + simple14::Test_7 test_7; + simple14::Test_7_mref test_7_mref = test_7.mref(); + + auto sequence_7_mref = test_7_mref.set_sequence_7(); + sequence_7_mref.resize(1); + + auto element_sequence = sequence_7_mref.front(); + element_sequence.set_field_7_3().as(50); + + REQUIRE(test_case.encoding(test_7.cref(),"\xC0\x87\x81\xC0\xB2",true)); + REQUIRE(test_case.decoding("\xC0\x87\x81\xC0\xB2",test_7.cref(),true)); + } + + SECTION("group present") + { + simple14::Test_7 test_7; + simple14::Test_7_mref test_7_mref = test_7.mref(); + + auto sequence_7_mref = test_7_mref.set_sequence_7(); + sequence_7_mref.resize(1); + + auto element_sequence = sequence_7_mref.front(); + element_sequence.set_field_7_3().as(50); + + auto group_7 = element_sequence.set_group_7(); + group_7.set_field_7_4().as(20); + + REQUIRE(test_case.encoding(test_7.cref(),"\xC0\x87\x81\xE0\xB2\x94",true)); + REQUIRE(test_case.decoding("\xC0\x87\x81\xE0\xB2\x94",test_7.cref(),true)); + } +} + +TEST_CASE("sequence with optional decimal encoder_V2/decoder_v2", "[sequence_with_optional_decimal_encoder_v2_decoder_v2]") +{ + fast_test_coding_case_v2 test_case; + + SECTION("decimal present") + { + simple14::Test_8 test_8; + simple14::Test_8_mref test_8_mref = test_8.mref(); + + auto sequence_8_mref = test_8_mref.set_sequence_8(); + sequence_8_mref.resize(1); + + auto element_sequence = sequence_8_mref.front(); + element_sequence.set_field_8_2().as(50); + element_sequence.set_field_8_3().as(10, 1); + + REQUIRE(test_case.encoding(test_8.cref(),"\xC0\x88\x81\xC0\xB2\x82\x8A",true)); + REQUIRE(test_case.decoding("\xC0\x88\x81\xC0\xB2\x82\x8A",test_8.cref(),true)); + } +} diff --git a/tests/simple12.xml b/tests/simple12.xml index db69f6e7..54e09d04 100644 --- a/tests/simple12.xml +++ b/tests/simple12.xml @@ -65,4 +65,8 @@ + diff --git a/tests/simple14.xml b/tests/simple14.xml index e7f9b916..f4f0b9e1 100644 --- a/tests/simple14.xml +++ b/tests/simple14.xml @@ -54,4 +54,20 @@ + +