diff --git a/examples/zmq_receiver_example.cpp b/examples/zmq_receiver_example.cpp index 0fe1220..142d4b9 100644 --- a/examples/zmq_receiver_example.cpp +++ b/examples/zmq_receiver_example.cpp @@ -1,4 +1,5 @@ #include "aare/ZmqSocketReceiver.hpp" +#include #include #include diff --git a/network_io/CMakeLists.txt b/network_io/CMakeLists.txt index d3f27fc..7d544dd 100644 --- a/network_io/CMakeLists.txt +++ b/network_io/CMakeLists.txt @@ -7,7 +7,9 @@ FetchContent_Declare( ) FetchContent_MakeAvailable(simdjson) - +# hide simdjson warnings by making the includes system includes +get_target_property(_inc simdjson INTERFACE_INCLUDE_DIRECTORIES) +target_include_directories(simdjson SYSTEM INTERFACE ${_inc}) add_library(network_io STATIC @@ -27,10 +29,10 @@ if(AARE_PYTHON_BINDINGS) set_property(TARGET file_io PROPERTY POSITION_INDEPENDENT_CODE ON) endif() -# if(AARE_TESTS) -# set(TestSources -# ${CMAKE_CURRENT_SOURCE_DIR}/test/NumpyFile.test.cpp -# ) -# target_sources(tests PRIVATE ${TestSources} ) -# target_link_libraries(tests PRIVATE core network_io) -# endif() +if(AARE_TESTS) + set(TestSources + ${CMAKE_CURRENT_SOURCE_DIR}/test/ZmqHeader.test.cpp + ) + target_sources(tests PRIVATE ${TestSources} ) + target_link_libraries(tests PRIVATE network_io core utils) +endif() \ No newline at end of file diff --git a/network_io/include/aare/ZmqHeader.hpp b/network_io/include/aare/ZmqHeader.hpp index 64ff7ca..c721d78 100644 --- a/network_io/include/aare/ZmqHeader.hpp +++ b/network_io/include/aare/ZmqHeader.hpp @@ -45,6 +45,34 @@ template <> simdjson_inline simdjson::simdjson_result simdjson::ondema return static_cast(val); } +/** + * @brief cast a simdjson::ondemand::value to a std::map +*/ +template <> simdjson_inline simdjson::simdjson_result> simdjson::ondemand::value::get() noexcept { + std::map map; + ondemand::object obj; + auto error = get_object().get(obj); + if (error) { + return error; + } + for (auto field : obj) { + simdjson::ondemand::raw_json_string tmp; + error = field.key().get(tmp); + if (error) { + return error; + } + error = field.value().get(tmp); + if (error) { + return error; + } + std::string_view key_view = field.unescaped_key(); + std::string key_str(key_view.data(), key_view.size()); + std::string_view value_view = field.value().get_string(); + map[key_str] = {value_view.data(), value_view.size()}; + } + return map; +} + } // namespace simdjson namespace aare { @@ -102,5 +130,7 @@ struct ZmqHeader { /** serialize struct to json string */ std::string to_string() const; void from_string(std::string &s); + // compare operator + bool operator==(const ZmqHeader &other) const ; }; } // namespace aare \ No newline at end of file diff --git a/network_io/src/ZmqHeader.cpp b/network_io/src/ZmqHeader.cpp index 93a81fc..3eff459 100644 --- a/network_io/src/ZmqHeader.cpp +++ b/network_io/src/ZmqHeader.cpp @@ -40,6 +40,13 @@ void write_map(std::string &s, const std::string &key, const std::map= 0; i--) { + if (s[i] == ',' or s[i] == ' ') { + s.pop_back(); + } else + break; + } s += "}, "; } void write_array(std::string &s, const std::string &key, const std::array &value) { @@ -171,18 +178,23 @@ void ZmqHeader::from_string(std::string &s) { } else if (key == "completeImage") { completeImage = uint64_t(field.value()) ? true : false; } else if (key == "addJsonHeader") { - for (auto field2 : field.value().get_object()) { - simdjson::ondemand::raw_json_string tmp; - auto error = field2.key().get(tmp); - std::string key2(tmp.raw()); - std::string val; - error = field2.value().get_string(val); - addJsonHeader[key2] = std::string(val); - } + addJsonHeader = std::map(field.value()); } else if (key == "rx_roi") { rx_roi = std::array(field.value()); } } } +bool ZmqHeader::operator==(const ZmqHeader &other) const { + return data == other.data && jsonversion == other.jsonversion && dynamicRange == other.dynamicRange && + fileIndex == other.fileIndex && ndetx == other.ndetx && ndety == other.ndety && npixelsx == other.npixelsx && + npixelsy == other.npixelsy && imageSize == other.imageSize && acqIndex == other.acqIndex && + frameIndex == other.frameIndex && progress == other.progress && fname == other.fname && + frameNumber == other.frameNumber && expLength == other.expLength && packetNumber == other.packetNumber && + detSpec1 == other.detSpec1 && timestamp == other.timestamp && modId == other.modId && row == other.row && + column == other.column && detSpec2 == other.detSpec2 && detSpec3 == other.detSpec3 && + detSpec4 == other.detSpec4 && detType == other.detType && version == other.version && + flipRows == other.flipRows && quad == other.quad && completeImage == other.completeImage && + addJsonHeader == other.addJsonHeader && rx_roi == other.rx_roi; +} } // namespace aare \ No newline at end of file diff --git a/network_io/test/ZmqHeader.test.cpp b/network_io/test/ZmqHeader.test.cpp new file mode 100644 index 0000000..60eb11f --- /dev/null +++ b/network_io/test/ZmqHeader.test.cpp @@ -0,0 +1,88 @@ +#include +#include "aare/ZmqHeader.hpp" +#include "aare/utils/logger.hpp" + + +using namespace aare; +TEST_CASE("Test ZmqHeader") { + ZmqHeader header; + header.npixelsx = 10; + header.npixelsy = 15; + header.data= 1; + header.jsonversion= 2; + header.dynamicRange= 32; + header.fileIndex= 4; + header.ndetx= 5; + header.ndety= 6; + header.imageSize= 4800; + header.acqIndex= 8; + header.frameIndex= 9; + header.progress= 0.1; + header.fname= "test"; + header.frameNumber= 11; + header.expLength= 12; + header.packetNumber= 13; + header.detSpec1= 14; + header.timestamp= 15; + header.modId= 16; + header.row= 17; + header.column= 18; + header.detSpec2= 19; + header.detSpec3= 20; + header.detSpec4= 21; + header.detType= 22; + header.version= 23; + header.flipRows= 24; + header.quad= 25; + header.completeImage= 1; + header.addJsonHeader= {{"key1", "value1"}, {"key2", "value2"}}; + header.rx_roi= {27, 28, 29, 30}; + + std::string json_header = "{" + "\"data\": 1, " + "\"jsonversion\": 2, " + "\"dynamicRange\": 32, " + "\"fileIndex\": 4, " + "\"ndetx\": 5, " + "\"ndety\": 6, " + "\"npixelsx\": 10, " + "\"npixelsy\": 15, " + "\"imageSize\": 4800, " + "\"acqIndex\": 8, " + "\"frameIndex\": 9, " + "\"progress\": 0.100000, " + "\"fname\": \"test\", " + "\"frameNumber\": 11, " + "\"expLength\": 12, " + "\"packetNumber\": 13, " + "\"detSpec1\": 14, " + "\"timestamp\": 15, " + "\"modId\": 16, " + "\"row\": 17, " + "\"column\": 18, " + "\"detSpec2\": 19, " + "\"detSpec3\": 20, " + "\"detSpec4\": 21, " + "\"detType\": 22, " + "\"version\": 23, " + "\"flipRows\": 24, " + "\"quad\": 25, " + "\"completeImage\": 1, " + "\"addJsonHeader\": {\"key1\": \"value1\", \"key2\": \"value2\"}, " + "\"rx_roi\": [27, 28, 29, 30]" + "}"; + + SECTION("Test converting ZmqHeader to json string"){ + REQUIRE(header.to_string() == json_header); + + } + SECTION("Test converting json string to ZmqHeader"){ + ZmqHeader header2; + header2.from_string(json_header); + REQUIRE(header2== header); + } + + + + +} diff --git a/utils/include/aare/utils/logger.hpp b/utils/include/aare/utils/logger.hpp index bf49489..80a1500 100644 --- a/utils/include/aare/utils/logger.hpp +++ b/utils/include/aare/utils/logger.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #define LOCATION std::string(__FILE__) + std::string(":") + std::to_string(__LINE__) + ":" + std::string(__func__) + ":" @@ -32,6 +33,17 @@ template std::ostream &operator<<(std::ostream &out, cons out << "]"; return out; } +// operator overlaod for std::map +template std::ostream &operator<<(std::ostream &out, const std::map &v) { + out << "{"; + size_t i = 0; + for (auto &kv : v) { + out << kv.first << ": " << kv.second << ((++i!=v.size())?", ":""); + } + + out << "}"; + return out; +} namespace aare {