diff --git a/src/mfast/coder/encoder/fast_encoder.cpp b/src/mfast/coder/encoder/fast_encoder.cpp index 27257ac5..ca36ba86 100644 --- a/src/mfast/coder/encoder/fast_encoder.cpp +++ b/src/mfast/coder/encoder/fast_encoder.cpp @@ -124,6 +124,16 @@ inline void fast_encoder_impl::visit(group_cref cref, int) { inline void fast_encoder_impl::visit(sequence_cref cref, int) { + if (cref.instruction()->optional() && !cref.present()) { + if (cref.instruction()->length_instruction()->pmap_size() > 0) + this->current_->set_next_bit(false); + if (cref.instruction()->length_instruction()->field_operator() != operator_constant && + cref.instruction()->length_instruction()->field_operator() != operator_default && + cref.instruction()->length_instruction()->field_operator() != operator_copy) + strm_.encode_null(); + return; + } + value_storage storage; uint32_mref length_mref(nullptr, &storage, diff --git a/src/mfast/coder/encoder_v2/fast_encoder_core.h b/src/mfast/coder/encoder_v2/fast_encoder_core.h index 345627ae..b90d169d 100644 --- a/src/mfast/coder/encoder_v2/fast_encoder_core.h +++ b/src/mfast/coder/encoder_v2/fast_encoder_core.h @@ -259,6 +259,17 @@ inline void fast_encoder_core::encode_field(const T &ext_ref, group_type_tag) { template inline void fast_encoder_core::encode_field(const T &ext_ref, sequence_type_tag) { + + if (ext_ref.get().instruction()->optional() && !ext_ref.present()) { + if (T::length_type::has_pmap_type::value) + this->current_->set_next_bit(false); + if(!std::is_same::value && + !std::is_same::value && + !std::is_same::value) + strm_.encode_null(); + return; + } + value_storage storage; typename T::length_type length = ext_ref.get_length(storage); diff --git a/src/mfast/ext_ref.h b/src/mfast/ext_ref.h index 33edb1d6..60bf81aa 100644 --- a/src/mfast/ext_ref.h +++ b/src/mfast/ext_ref.h @@ -167,6 +167,8 @@ class ext_cref { } std::size_t size() const { return base_.size(); } + bool present() const { return base_.present(); } + private: sequence_cref base_; }; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fb9d29bc..4cd388e6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -74,7 +74,7 @@ add_executable (mfast_test aggregate_view_test.cpp simple_coder_test.cpp sequence_encoder_decoder_v2.cpp - sequence_encoder_decoder_v2.cpp + sequence_encoder_decoder.cpp scp_reset_test.cpp template_repo_base.cpp message_pmap_test.cpp diff --git a/tests/encoder_decoder_test.cpp b/tests/encoder_decoder_test.cpp index 96271e48..768b663d 100644 --- a/tests/encoder_decoder_test.cpp +++ b/tests/encoder_decoder_test.cpp @@ -245,3 +245,38 @@ TEST_CASE("simple optional field with default value encoder/decoder","[optional_ REQUIRE(test_case.decoding("\xD0\x86\x82",test_6.cref(),true)); } } + +TEST_CASE("sequence optional with constant length encoder/decoder","[optional_sequence_with_constant_length_encoder_decoder]") +{ + fast_test_coding_case test_case; + + SECTION("encode fields without sequence") + { + simple12::Test_7 test_7; + simple12::Test_7_mref test_7_mref = test_7.mref(); + test_7_mref.set_field_7_1().as(1); + REQUIRE(test_case.encoding(test_7.cref(),"\xE0\x87\x82",true)); + REQUIRE(test_case.decoding("\xE0\x87\x82",test_7.cref(),true)); + } + + SECTION("encode fields with sequence") + { + simple12::Test_7 test_7; + simple12::Test_7_mref test_7_mref = test_7.mref(); + test_7_mref.set_field_7_1().as(1); + + { + 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_4().as(1); + element_sequence.set_field_7_5().as(1); + } + } + + REQUIRE(test_case.encoding(test_7.cref(),"\xF0\x87\x82\xa0\x82\x82",true)); + REQUIRE(test_case.decoding("\xF0\x87\x82\xa0\x82\x82",test_7.cref(),true)); + } +} diff --git a/tests/encoder_decoder_test_v2.cpp b/tests/encoder_decoder_test_v2.cpp index 4846e84a..0aabce9d 100644 --- a/tests/encoder_decoder_test_v2.cpp +++ b/tests/encoder_decoder_test_v2.cpp @@ -22,7 +22,7 @@ TEST_CASE("simple field and sequence optional encoder_v2/decoder_v2","[field_seq // 1 : Set Template Id. // 1 : Set Field field_1_1 // 0 : XXX - REQUIRE(test_case.encoding(test_1.cref(),"\xE0\x81\x82\x81",true)); + REQUIRE(test_case.encoding(test_1.cref(),"\xE0\x81\x82\x80",true)); REQUIRE(test_case.decoding("\xE0\x81\x82\x80",test_1.cref(),true)); } @@ -246,3 +246,38 @@ TEST_CASE("simple optional field with default value encoder_v2/decoder_v2","[opt REQUIRE(test_case.decoding("\xD0\x86\x82",test_6.cref(),true)); } } + +TEST_CASE("sequence optional with constant length encoder_v2/decoder_v2","[optional_sequence_with_constant_length_encoder_v2/decoder_v2]") +{ + fast_test_coding_case_v2 test_case; + + SECTION("encode fields without sequence") + { + simple12::Test_7 test_7; + simple12::Test_7_mref test_7_mref = test_7.mref(); + test_7_mref.set_field_7_1().as(1); + REQUIRE(test_case.encoding(test_7.cref(),"\xE0\x87\x82",true)); + REQUIRE(test_case.decoding("\xE0\x87\x82",test_7.cref(),true)); + } + + SECTION("encode fields with sequence") + { + simple12::Test_7 test_7; + simple12::Test_7_mref test_7_mref = test_7.mref(); + test_7_mref.set_field_7_1().as(1); + + { + 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_4().as(1); + element_sequence.set_field_7_5().as(1); + } + } + + REQUIRE(test_case.encoding(test_7.cref(),"\xF0\x87\x82\xa0\x82\x82",true)); + REQUIRE(test_case.decoding("\xF0\x87\x82\xa0\x82\x82",test_7.cref(),true)); + } +} diff --git a/tests/group_encoder_decoder.cpp b/tests/group_encoder_decoder.cpp index 00d19977..029f5d9f 100644 --- a/tests/group_encoder_decoder.cpp +++ b/tests/group_encoder_decoder.cpp @@ -39,4 +39,53 @@ TEST_CASE("field with group encoder/decoder","[field_without_group_encoder_decod REQUIRE(test_case.decoding("\xE0\x81\x9F\xA8\x80\x8B",test_1.cref(),true)); } +TEST_CASE("optional group encoder/decoder","[optional_group_encoder_decoder]") +{ + fast_test_coding_case test_case; + + SECTION("No group") + { + simple13::Test_4 test_4; + + REQUIRE(test_case.encoding(test_4.cref(),"\xC0\x84",true)); + REQUIRE(test_case.decoding("\xC0\x84",test_4.cref(),true)); + } + + SECTION("With group") + { + simple13::Test_4 test_4; + simple13::Test_4_mref test_4_mref = test_4.mref(); + + // set group + { + auto group_1 = test_4_mref.set_group_4_1(); + auto sequence_4_mref = group_1.set_sequence_4(); + sequence_4_mref.resize(1); + auto element_sequence = sequence_4_mref.front(); + element_sequence.set_field_4_3().as(1); + } + REQUIRE(test_case.encoding(test_4.cref(),"\xE0\x84\x80\xC0\x81",true)); + REQUIRE(test_case.decoding("\xE0\x84\x80\xC0\x81",test_4.cref(),true)); + } + + SECTION("With group sequence and field") + { + simple13::Test_4 test_4; + simple13::Test_4_mref test_4_mref = test_4.mref(); + + // set group + { + auto group_1 = test_4_mref.set_group_4_1(); + auto sequence_4_mref = group_1.set_sequence_4(); + sequence_4_mref.resize(1); + auto element_sequence = sequence_4_mref.front(); + element_sequence.set_field_4_3().as(1); + + group_1.set_field_4_4().as(10); + } + + REQUIRE(test_case.encoding(test_4.cref(),"\xE0\x84\xC0\xC0\x81\x8B",true)); + REQUIRE(test_case.decoding("\xE0\x84\xC0\xC0\x81\x8B",test_4.cref(),true)); + } +} diff --git a/tests/group_encoder_decoder_v2.cpp b/tests/group_encoder_decoder_v2.cpp index 1c5a624e..bc3c8442 100644 --- a/tests/group_encoder_decoder_v2.cpp +++ b/tests/group_encoder_decoder_v2.cpp @@ -39,4 +39,53 @@ TEST_CASE("field with group encoder_v2/decoder_v2","[field_without_group_encoder REQUIRE(test_case.decoding("\xE0\x81\x9F\xA8\x80\x8B",test_1.cref(),true)); } +TEST_CASE("optional group encoder_v2/decoder_v2","[optional_group_encoder_v2_decoder_v2]") +{ + fast_test_coding_case_v2 test_case; + + SECTION("No group") + { + simple13::Test_4 test_4; + + REQUIRE(test_case.encoding(test_4.cref(),"\xC0\x84",true)); + REQUIRE(test_case.decoding("\xC0\x84",test_4.cref(),true)); + } + + SECTION("With group") + { + simple13::Test_4 test_4; + simple13::Test_4_mref test_4_mref = test_4.mref(); + + // set group + { + auto group_1 = test_4_mref.set_group_4_1(); + auto sequence_4_mref = group_1.set_sequence_4(); + sequence_4_mref.resize(1); + auto element_sequence = sequence_4_mref.front(); + element_sequence.set_field_4_3().as(1); + } + REQUIRE(test_case.encoding(test_4.cref(),"\xE0\x84\x80\xC0\x81",true)); + REQUIRE(test_case.decoding("\xE0\x84\x80\xC0\x81",test_4.cref(),true)); + } + + SECTION("With group sequence and field") + { + simple13::Test_4 test_4; + simple13::Test_4_mref test_4_mref = test_4.mref(); + + // set group + { + auto group_1 = test_4_mref.set_group_4_1(); + auto sequence_4_mref = group_1.set_sequence_4(); + sequence_4_mref.resize(1); + auto element_sequence = sequence_4_mref.front(); + element_sequence.set_field_4_3().as(1); + + group_1.set_field_4_4().as(10); + } + + REQUIRE(test_case.encoding(test_4.cref(),"\xE0\x84\xC0\xC0\x81\x8B",true)); + REQUIRE(test_case.decoding("\xE0\x84\xC0\xC0\x81\x8B",test_4.cref(),true)); + } +} diff --git a/tests/sequence_encoder_decoder.cpp b/tests/sequence_encoder_decoder.cpp index 59bd9d29..e2d1fb8c 100644 --- a/tests/sequence_encoder_decoder.cpp +++ b/tests/sequence_encoder_decoder.cpp @@ -130,4 +130,110 @@ TEST_CASE("sequence optional none operator by length encoder/decoder","[sequence REQUIRE(test_case.decoding("\xC0\x84\x82\xC0\xB3\x8B",test_4.cref(),true)); } +TEST_CASE("sequence inside sequence encoder/decoder","[sequence_inside_sequence_encoder_decoder]") +{ + fast_test_coding_case test_case; + + SECTION("outside sequence") + { + simple14::Test_5 test_5; + simple14::Test_5_mref test_5_mref = test_5.mref(); + + test_5_mref.set_field_5_2().as(1); + + auto sequence_5_1_mref = test_5_mref.set_sequence_5_1(); + sequence_5_1_mref.resize(1); + + { + auto element_sequence = sequence_5_1_mref.front(); + element_sequence.set_field_5_4().as(50); + } + + REQUIRE(test_case.encoding(test_5.cref(),"\xD0\x85\x81\x81\xC0\xB3",true)); + REQUIRE(test_case.decoding("\xD0\x85\x81\x81\xC0\xB3",test_5.cref(),true)); + } + + SECTION("inside sequence") + { + simple14::Test_5 test_5; + simple14::Test_5_mref test_5_mref = test_5.mref(); + + test_5_mref.set_field_5_2().as(1); + + auto sequence_5_1_mref = test_5_mref.set_sequence_5_1(); + sequence_5_1_mref.resize(1); + + { + auto element_sequence = sequence_5_1_mref.front(); + element_sequence.set_field_5_4().as(50); + + auto sequence_5_2_mref = element_sequence.set_sequence_5_2(); + sequence_5_2_mref.resize(1); + + { + auto element_sequence_inside = sequence_5_2_mref.front(); + element_sequence_inside.set_field_5_6().as(50); + } + } + REQUIRE(test_case.encoding(test_5.cref(),"\xD0\x85\x81\x81\xE0\xB3\x82\xB2",true)); + REQUIRE(test_case.decoding("\xD0\x85\x81\x81\xE0\xB3\x82\xB2",test_5.cref(),true)); + } +} + +TEST_CASE("group sequence inside sequence encoder/decoder","[group_sequence_inside_sequence_encoder_decoder]") +{ + fast_test_coding_case test_case; + + SECTION("outside sequence") + { + simple14::Test_6 test_6; + simple14::Test_6_mref test_6_mref = test_6.mref(); + + // set group + { + auto group_6 = test_6_mref.set_group_6(); + auto sequence_6_1_mref = group_6.set_sequence_6_1(); + sequence_6_1_mref.resize(1); + + //set sequence + { + auto element_sequence = sequence_6_1_mref.front(); + element_sequence.set_field_6_3().as(50); + } + } + + REQUIRE(test_case.encoding(test_6.cref(),"\xC0\x86\x81\xC0\xB2",true)); + REQUIRE(test_case.decoding("\xC0\x86\x81\xC0\xB2",test_6.cref(),true)); + } + + SECTION("inside sequence") + { + simple14::Test_6 test_6; + simple14::Test_6_mref test_6_mref = test_6.mref(); + + // set group + { + auto group_6 = test_6_mref.set_group_6(); + auto sequence_6_1_mref = group_6.set_sequence_6_1(); + sequence_6_1_mref.resize(1); + + //set sequence + { + auto element_sequence = sequence_6_1_mref.front(); + element_sequence.set_field_6_3().as(50); + + auto sequence_6_2_mref = element_sequence.set_sequence_6_2(); + sequence_6_2_mref.resize(1); + + { + auto element_sequence_inside = sequence_6_2_mref.front(); + element_sequence_inside.set_field_6_6().as(50); + } + } + } + + REQUIRE(test_case.encoding(test_6.cref(),"\xC0\x86\x81\xD0\xB2\x82\xB2",true)); + REQUIRE(test_case.decoding("\xC0\x86\x81\xD0\xB2\x82\xB2",test_6.cref(),true)); + } +} diff --git a/tests/sequence_encoder_decoder_v2.cpp b/tests/sequence_encoder_decoder_v2.cpp index a7cc992f..bbf05cdd 100644 --- a/tests/sequence_encoder_decoder_v2.cpp +++ b/tests/sequence_encoder_decoder_v2.cpp @@ -131,3 +131,111 @@ TEST_CASE("sequence optional none operator by length encoder_V2/decoder_v2","[se 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)); } + +TEST_CASE("sequence inside sequence encoder_V2/decoder_v2","[sequence_inside_sequence_encoder_v2_decoder_v2]") +{ + fast_test_coding_case_v2 test_case; + + SECTION("outside sequence") + { + simple14::Test_5 test_5; + simple14::Test_5_mref test_5_mref = test_5.mref(); + + test_5_mref.set_field_5_2().as(1); + + auto sequence_5_1_mref = test_5_mref.set_sequence_5_1(); + sequence_5_1_mref.resize(1); + + { + auto element_sequence = sequence_5_1_mref.front(); + element_sequence.set_field_5_4().as(50); + } + + REQUIRE(test_case.encoding(test_5.cref(),"\xD0\x85\x81\x81\xC0\xB3",true)); + REQUIRE(test_case.decoding("\xD0\x85\x81\x81\xC0\xB3",test_5.cref(),true)); + } + + SECTION("inside sequence") + { + simple14::Test_5 test_5; + simple14::Test_5_mref test_5_mref = test_5.mref(); + + test_5_mref.set_field_5_2().as(1); + + auto sequence_5_1_mref = test_5_mref.set_sequence_5_1(); + sequence_5_1_mref.resize(1); + + { + auto element_sequence = sequence_5_1_mref.front(); + element_sequence.set_field_5_4().as(50); + + auto sequence_5_2_mref = element_sequence.set_sequence_5_2(); + sequence_5_2_mref.resize(1); + + { + auto element_sequence_inside = sequence_5_2_mref.front(); + element_sequence_inside.set_field_5_6().as(50); + } + } + + REQUIRE(test_case.encoding(test_5.cref(),"\xD0\x85\x81\x81\xE0\xB3\x82\xB2",true)); + REQUIRE(test_case.decoding("\xD0\x85\x81\x81\xE0\xB3\x82\xB2",test_5.cref(),true)); + } +} + +TEST_CASE("group sequence inside sequence encoder_V2/decoder_v2","[group_sequence_inside_sequence_encoder_v2_decoder_v2]") +{ + fast_test_coding_case_v2 test_case; + + SECTION("outside sequence") + { + simple14::Test_6 test_6; + simple14::Test_6_mref test_6_mref = test_6.mref(); + + // set group + { + auto group_6 = test_6_mref.set_group_6(); + auto sequence_6_1_mref = group_6.set_sequence_6_1(); + sequence_6_1_mref.resize(1); + + //set sequence + { + auto element_sequence = sequence_6_1_mref.front(); + element_sequence.set_field_6_3().as(50); + } + } + + REQUIRE(test_case.encoding(test_6.cref(),"\xC0\x86\x81\xC0\xB2",true)); + REQUIRE(test_case.decoding("\xC0\x86\x81\xC0\xB2",test_6.cref(),true)); + } + + SECTION("inside sequence") + { + simple14::Test_6 test_6; + simple14::Test_6_mref test_6_mref = test_6.mref(); + + // set group + { + auto group_6 = test_6_mref.set_group_6(); + auto sequence_6_1_mref = group_6.set_sequence_6_1(); + sequence_6_1_mref.resize(1); + + //set sequence + { + auto element_sequence = sequence_6_1_mref.front(); + element_sequence.set_field_6_3().as(50); + + auto sequence_6_2_mref = element_sequence.set_sequence_6_2(); + sequence_6_2_mref.resize(1); + + { + auto element_sequence_inside = sequence_6_2_mref.front(); + element_sequence_inside.set_field_6_6().as(50); + } + } + } + + REQUIRE(test_case.encoding(test_6.cref(),"\xC0\x86\x81\xD0\xB2\x82\xB2",true)); + REQUIRE(test_case.decoding("\xC0\x86\x81\xD0\xB2\x82\xB2",test_6.cref(),true)); + } +} diff --git a/tests/simple12.xml b/tests/simple12.xml index 2465c03d..db69f6e7 100644 --- a/tests/simple12.xml +++ b/tests/simple12.xml @@ -3,8 +3,9 @@ + diff --git a/tests/simple14.xml b/tests/simple14.xml index 97390a38..e7f9b916 100644 --- a/tests/simple14.xml +++ b/tests/simple14.xml @@ -28,4 +28,30 @@ + +