From c11bfa4217d84caace9a4ab570e3bca38586d5c9 Mon Sep 17 00:00:00 2001 From: Roberto Martin Fantini Date: Fri, 30 May 2025 11:24:37 +0200 Subject: [PATCH 1/6] Null dangling pointer for the case of pmap --- src/mfast/coder/decoder/fast_decoder.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mfast/coder/decoder/fast_decoder.cpp b/src/mfast/coder/decoder/fast_decoder.cpp index 68b21373..d757e059 100644 --- a/src/mfast/coder/decoder/fast_decoder.cpp +++ b/src/mfast/coder/decoder/fast_decoder.cpp @@ -290,6 +290,7 @@ message_type *fast_decoder_impl::decode_segment(fast_istreambuf &sb) { for (auto &&field : message->ref()) { apply_mutator(*this, field); } + this->current_ = nullptr; return message; } From 105757557abf0aad82b526612f84f81c66747b2b Mon Sep 17 00:00:00 2001 From: Roberto Martin Fantini Date: Fri, 30 May 2025 11:55:29 +0200 Subject: [PATCH 2/6] Correct enum code --- src/mfast/enum_ref.h | 10 ++++++++++ src/mfast/ext_ref.h | 2 -- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/mfast/enum_ref.h b/src/mfast/enum_ref.h index b1b4f99e..e12f763c 100644 --- a/src/mfast/enum_ref.h +++ b/src/mfast/enum_ref.h @@ -45,6 +45,15 @@ class MFAST_EXPORT enum_cref : public field_cref { } bool is_boolean() const; +protected: + friend class mfast::detail::codec_helper; + + void save_to(value_storage &v) const { + v.of_uint64.content_ = this->storage()->of_uint64.content_; + v.defined(true); + v.present(this->present()); + } + private: enum_cref &operator=(const enum_cref &); }; @@ -70,6 +79,7 @@ class enum_mref : public make_field_mref { enum_mref(const enum_mref &) = default; + explicit enum_mref(const field_mref_base &other) : base_type(other) {} void as(const enum_cref &cref) const { if (cref.absent()) { this->omit(); diff --git a/src/mfast/ext_ref.h b/src/mfast/ext_ref.h index cba11441..c4ef130b 100644 --- a/src/mfast/ext_ref.h +++ b/src/mfast/ext_ref.h @@ -250,12 +250,10 @@ class ext_mref : public ext_ref_properties { storage->present(true); } return mref_type(base_); - ; } cref_type get() const { return cref_type(base_); - ; } bool present() const { return !this->optional() || base_.present(); } From 4e3cb4d4af7fa57a19d086638fe4c714146e8027 Mon Sep 17 00:00:00 2001 From: Roberto Martin Fantini Date: Fri, 30 May 2025 11:56:14 +0200 Subject: [PATCH 3/6] add unit test for the enum case --- tests/CMakeLists.txt | 5 ++++- tests/enum_encoder_decoder.cpp | 19 +++++++++++++++++++ tests/enum_encoder_decoder_v2.cpp | 19 +++++++++++++++++++ tests/fast_test_coding_case.hpp | 2 +- tests/fast_test_coding_case_v2.hpp | 2 +- tests/simple16.xml | 21 +++++++++++++++++++++ 6 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 tests/enum_encoder_decoder.cpp create mode 100644 tests/enum_encoder_decoder_v2.cpp create mode 100644 tests/simple16.xml diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f4fe2e0b..2af8f927 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -24,7 +24,7 @@ FASTTYPEGEN_TARGET(simple_types12 simple12.xml) FASTTYPEGEN_TARGET(simple_types13 simple13.xml) FASTTYPEGEN_TARGET(simple_types14 simple14.xml) FASTTYPEGEN_TARGET(simple_types15 simple15.xml) - +FASTTYPEGEN_TARGET(simple_types16 simple16.xml) FASTTYPEGEN_TARGET(test_types1 test1.xml test2.xml) FASTTYPEGEN_TARGET(test_types3 test3.xml) @@ -70,6 +70,7 @@ add_executable (mfast_test ${FASTTYPEGEN_simple_types13_OUTPUTS} ${FASTTYPEGEN_simple_types14_OUTPUTS} ${FASTTYPEGEN_simple_types15_OUTPUTS} + ${FASTTYPEGEN_simple_types16_OUTPUTS} fast_type_gen_test.cpp dictionary_builder_test.cpp json_test.cpp @@ -82,6 +83,8 @@ add_executable (mfast_test scp_reset_test.cpp template_repo_base.cpp message_pmap_test.cpp + enum_encoder_decoder_v2.cpp + enum_encoder_decoder.cpp ) target_link_libraries (mfast_test diff --git a/tests/enum_encoder_decoder.cpp b/tests/enum_encoder_decoder.cpp new file mode 100644 index 00000000..9e89d59f --- /dev/null +++ b/tests/enum_encoder_decoder.cpp @@ -0,0 +1,19 @@ +#include "catch.hpp" +#include + +#include "fast_test_coding_case.hpp" +#include "byte_stream.h" + +#include "simple16.h" + +using namespace test::coding; + +TEST_CASE("enum test encoder/decoder","[enum_encoder_decoder]") +{ + fast_test_coding_case test_case; + simple16::Test_1 test_1; + simple16::Test_1_mref test_1_mref = test_1.mref(); + test_1_mref.set_discrete().as_Three(); + REQUIRE(test_case.encoding(test_1.cref(),"\xC0\x81\x83",true)); + REQUIRE(test_case.decoding("\xC0\x81\x83",test_1.cref(),true)); +} diff --git a/tests/enum_encoder_decoder_v2.cpp b/tests/enum_encoder_decoder_v2.cpp new file mode 100644 index 00000000..281a041a --- /dev/null +++ b/tests/enum_encoder_decoder_v2.cpp @@ -0,0 +1,19 @@ +#include "catch.hpp" +#include + +#include "fast_test_coding_case_v2.hpp" +#include "byte_stream.h" + +#include "simple16.h" + +using namespace test::coding; + +TEST_CASE("enum test encoder_V2/decoder_v2","[enum_encoder_v2_decoder_v2]") +{ + fast_test_coding_case_v2 test_case; + simple16::Test_1 test_1; + simple16::Test_1_mref test_1_mref = test_1.mref(); + test_1_mref.set_discrete().as_Three(); + REQUIRE(test_case.encoding(test_1.cref(),"\xC0\x81\x83",true)); + REQUIRE(test_case.decoding("\xC0\x81\x83",test_1.cref(),true)); +} diff --git a/tests/fast_test_coding_case.hpp b/tests/fast_test_coding_case.hpp index 0a70a07f..509d32b9 100644 --- a/tests/fast_test_coding_case.hpp +++ b/tests/fast_test_coding_case.hpp @@ -32,7 +32,7 @@ class fast_test_coding_case if (result == byte_stream(buffer, encoded_size)) return true; - INFO( "Got \"" << byte_stream(buffer, encoded_size) << "\" instead." ); + INFO( "Got \"" << byte_stream(buffer, encoded_size) << "\" instead." ); return false; } diff --git a/tests/fast_test_coding_case_v2.hpp b/tests/fast_test_coding_case_v2.hpp index 42dc0967..1e8bf49b 100644 --- a/tests/fast_test_coding_case_v2.hpp +++ b/tests/fast_test_coding_case_v2.hpp @@ -27,7 +27,7 @@ class fast_test_coding_case_v2 if (result == byte_stream(buffer, encoded_size)) return true; - INFO( "Got \"" << byte_stream(buffer, encoded_size) << "\" instead." ); + INFO( "Got \"" << byte_stream(buffer, encoded_size) << "\" instead." ); return false; } diff --git a/tests/simple16.xml b/tests/simple16.xml new file mode 100644 index 00000000..e32fafc2 --- /dev/null +++ b/tests/simple16.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + From 8d6b5224d7e2e7d2e40ef8c805cdcd13fdabd570 Mon Sep 17 00:00:00 2001 From: Roberto Martin Fantini Date: Fri, 30 May 2025 12:37:49 +0200 Subject: [PATCH 4/6] add Xetra timestamp code --- CMakeLists.txt | 2 ++ src/mfast/xml_parser/CMakeLists.txt | 9 +++++++++ src/mfast/xml_parser/templates_builder.cpp | 7 +++++++ 3 files changed, 18 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 10b4a17f..d6393a85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ project (mFAST VERSION 1.3.0 LANGUAGES CXX) option(BUILD_TESTS "Build tests" ON) option(BUILD_EXAMPLES "Build examples" ON) option(BUILD_PACKAGES "Build packages" ON) +option(XETRA_FAST_SPECIFICATION "Xetra Fast 1.2 specification" OFF) # global options set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) @@ -96,4 +97,5 @@ message(STATUS "BUILD_SHARED_LIBS: " ${BUILD_SHARED_LIBS}) message(STATUS "BUILD_TESTS: " ${BUILD_TESTS}) message(STATUS "BUILD_EXAMPLES: " ${BUILD_EXAMPLES}) message(STATUS "BUILD_PACKAGES: " ${BUILD_PACKAGES}) +message(STATUS "XETRA_FAST_SPECIFICATION: " ${XETRA_FAST_SPECIFICATION}) message(STATUS "") diff --git a/src/mfast/xml_parser/CMakeLists.txt b/src/mfast/xml_parser/CMakeLists.txt index 028c99fc..95bb6288 100644 --- a/src/mfast/xml_parser/CMakeLists.txt +++ b/src/mfast/xml_parser/CMakeLists.txt @@ -22,6 +22,11 @@ if (UNIX) set_target_properties(mfast_xml_parser_static PROPERTIES OUTPUT_NAME mfast_xml_parser) endif() + +if(XETRA_FAST_SPECIFICATION) + target_compile_definitions(mfast_xml_parser_static PRIVATE XETRA_FAST_SPECIFICATION) +endif(XETRA_FAST_SPECIFICATION) + install(TARGETS mfast_xml_parser_static EXPORT mFASTTargets FILE_SET HEADERS) @@ -40,6 +45,10 @@ if (BUILD_SHARED_LIBS) set_property(TARGET mfast_xml_parser PROPERTY VERSION ${MFAST_VERSION}) set_property(TARGET mfast_xml_parser PROPERTY SOVERSION ${MFAST_VERSION}) + if(XETRA_FAST_SPECIFICATION) + target_compile_definitions(mfast_xml_parser PRIVATE XETRA_FAST_SPECIFICATION) + endif(XETRA_FAST_SPECIFICATION) + install(TARGETS mfast_xml_parser EXPORT mFASTTargets FILE_SET HEADERS) diff --git a/src/mfast/xml_parser/templates_builder.cpp b/src/mfast/xml_parser/templates_builder.cpp index 9b871852..6a1ecee0 100644 --- a/src/mfast/xml_parser/templates_builder.cpp +++ b/src/mfast/xml_parser/templates_builder.cpp @@ -67,6 +67,13 @@ templates_builder::templates_builder(dynamic_templates_description *definition, string_value_storage()); this->member["string"] = &ascii_field_instruction_prototype; +#ifdef XETRA_FAST_SPECIFICATION + static const int64_field_instruction timestamp_field_instruction_prototype( + operator_none, presence_mandatory, 0, nullptr, "", nullptr, + int_value_storage()); + this->member["timestamp"] = ×tamp_field_instruction_prototype; +#endif + static const byte_vector_field_instruction byte_vector_field_instruction_prototype( operator_none, presence_mandatory, 0, nullptr, "", nullptr, From e89b2e3ed6ae155380db5661c06d2d0679f5572f Mon Sep 17 00:00:00 2001 From: Roberto Martin Fantini Date: Fri, 30 May 2025 12:38:54 +0200 Subject: [PATCH 5/6] Add unit test for the case of the Xetra timestamp --- tests/CMakeLists.txt | 16 +++++++++++++++- tests/simple17.xml | 14 ++++++++++++++ tests/timestamp_encoder_decoder.cpp | 23 +++++++++++++++++++++++ tests/timestamp_encoder_decoder_v2.cpp | 20 ++++++++++++++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 tests/simple17.xml create mode 100644 tests/timestamp_encoder_decoder.cpp create mode 100644 tests/timestamp_encoder_decoder_v2.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2af8f927..be7a7a86 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -26,13 +26,17 @@ FASTTYPEGEN_TARGET(simple_types14 simple14.xml) FASTTYPEGEN_TARGET(simple_types15 simple15.xml) FASTTYPEGEN_TARGET(simple_types16 simple16.xml) +if(XETRA_FAST_SPECIFICATION) + FASTTYPEGEN_TARGET(simple_types17 simple17.xml) +endif(XETRA_FAST_SPECIFICATION) + FASTTYPEGEN_TARGET(test_types1 test1.xml test2.xml) FASTTYPEGEN_TARGET(test_types3 test3.xml) FASTTYPEGEN_TARGET(test_types4 test4.xml) FASTTYPEGEN_TARGET(test_types5 test5.xml) FASTTYPEGEN_TARGET(test_scp scp.xml) -add_executable (mfast_test +set(test_sources test_main.cpp arena_allocator_test.cpp field_ref_test.cpp @@ -87,6 +91,16 @@ add_executable (mfast_test enum_encoder_decoder.cpp ) +if(XETRA_FAST_SPECIFICATION) + set(test_sources ${test_sources} + ${FASTTYPEGEN_simple_types17_OUTPUTS} + timestamp_encoder_decoder_v2.cpp + timestamp_encoder_decoder.cpp + ) +endif(XETRA_FAST_SPECIFICATION) + +add_executable (mfast_test ${test_sources}) + target_link_libraries (mfast_test mfast_static mfast_coder_static diff --git a/tests/simple17.xml b/tests/simple17.xml new file mode 100644 index 00000000..7da2134c --- /dev/null +++ b/tests/simple17.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/tests/timestamp_encoder_decoder.cpp b/tests/timestamp_encoder_decoder.cpp new file mode 100644 index 00000000..77798411 --- /dev/null +++ b/tests/timestamp_encoder_decoder.cpp @@ -0,0 +1,23 @@ +#include "catch.hpp" +#include + +#include "fast_test_coding_case.hpp" +#include "byte_stream.h" + +#include "simple17.h" + +using namespace test::coding; + +TEST_CASE("timestamp test encoder/decoder","[timestamp_encoder_decoder]") +{ + fast_test_coding_case test_case; + simple17::Test_1 test_1; + simple17::Test_1_mref test_1_mref = test_1.mref(); + test_1_mref.set_field1().as(1); + test_1_mref.set_TransactTime().as(2); + REQUIRE(test_case.encoding(test_1.cref(),"\xF0\x81\x81\x83",true)); + REQUIRE(test_case.decoding("\xF0\x81\x81\x83",test_1.cref(),true)); +} + + + diff --git a/tests/timestamp_encoder_decoder_v2.cpp b/tests/timestamp_encoder_decoder_v2.cpp new file mode 100644 index 00000000..c326ae55 --- /dev/null +++ b/tests/timestamp_encoder_decoder_v2.cpp @@ -0,0 +1,20 @@ +#include "catch.hpp" +#include + +#include "fast_test_coding_case_v2.hpp" +#include "byte_stream.h" + +#include "simple17.h" + +using namespace test::coding; + +TEST_CASE("timestamp test encoder_V2/decoder_v2","[timestamp_encoder_v2_decoder_v2]") +{ + fast_test_coding_case_v2 test_case; + simple17::Test_1 test_1; + simple17::Test_1_mref test_1_mref = test_1.mref(); + test_1_mref.set_field1().as(1); + test_1_mref.set_TransactTime().as(2); + REQUIRE(test_case.encoding(test_1.cref(),"\xF0\x81\x81\x83",true)); + REQUIRE(test_case.decoding("\xF0\x81\x81\x83",test_1.cref(),true)); +} \ No newline at end of file From cbad7d656456c46da51634b662b1d95a44db48af Mon Sep 17 00:00:00 2001 From: Roberto Martin Fantini Date: Fri, 30 May 2025 13:20:32 +0200 Subject: [PATCH 6/6] Add Xetra compilation --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f2bc96cc..cf167187 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -16,7 +16,7 @@ jobs: run: curl -L https://archives.boost.io/release/1.72.0/source/boost_1_72_0.tar.gz | tar zx shell: bash - name: configure - run: cmake -Bbuild -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON + run: cmake -Bbuild -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DXETRA_FAST_SPECIFICATION=ON - name: build run: cmake --build build --parallel 2 - name: test