diff --git a/libsrc/core/archive.hpp b/libsrc/core/archive.hpp index 1fedde76..8c45baf2 100644 --- a/libsrc/core/archive.hpp +++ b/libsrc/core/archive.hpp @@ -153,6 +153,9 @@ namespace ngcore const VersionInfo& GetVersion(const std::string& library) { return version_map[library]; } + // only used for PyArchive + virtual void NeedsVersion(const std::string& library, const std::string& version) {} + // Pure virtual functions that have to be implemented by In-/OutArchive virtual Archive & operator & (double & d) = 0; virtual Archive & operator & (int & i) = 0; @@ -900,6 +903,7 @@ namespace ngcore private: pybind11::list lst; size_t index = 0; + std::map version_needed; protected: using ARCHIVE::stream; using ARCHIVE::version_map; @@ -915,9 +919,26 @@ namespace ngcore { stream = std::make_shared (pybind11::cast(lst[pybind11::len(lst)-1])); - *this & version_map; + *this & version_needed; + logger->debug("versions needed for unpickling = {}", version_needed); + for(auto& libversion : version_needed) + if(libversion.second > GetLibraryVersion(libversion.first)) + throw Exception("Error in unpickling data:\nLibrary " + libversion.first + + " must be at least " + libversion.second.to_string()); stream = std::make_shared (pybind11::cast(lst[pybind11::len(lst)-2])); + *this & version_map; + stream = std::make_shared + (pybind11::cast(lst[pybind11::len(lst)-3])); + } + } + + void NeedsVersion(const std::string& library, const std::string& version) override + { + if(Output()) + { + logger->debug("Need version {} of library {}.", version, library); + version_needed[library] = version_needed[library] > version ? version_needed[library] : version; } } @@ -936,6 +957,12 @@ namespace ngcore lst.append(pybind11::bytes(std::static_pointer_cast(stream)->str())); stream = std::make_shared(); *this & GetLibraryVersions(); + FlushBuffer(); + lst.append(pybind11::bytes(std::static_pointer_cast(stream)->str())); + stream = std::make_shared(); + logger->debug("Writeout version needed = {}", version_needed); + *this & version_needed; + FlushBuffer(); lst.append(pybind11::bytes(std::static_pointer_cast(stream)->str())); return lst; } @@ -949,17 +976,17 @@ namespace ngcore PyArchive ar; ar & self; auto output = pybind11::make_tuple(ar.WriteOut()); - NETGEN_DEBUG_LOG(GetLogger("Archive"), "pickling output for object of type " + - Demangle(typeid(T).name()) + " = " + - std::string(pybind11::str(output))); + GetLogger("Archive")->trace("Pickling output for object of type {} = {}", + Demangle(typeid(T).name()), + std::string(pybind11::str(output))); return output; }, [](pybind11::tuple state) { T* val = nullptr; - NETGEN_DEBUG_LOG(GetLogger("Archive"), "State for unpickling of object of type " + - Demangle(typeid(T).name()) + " = " + - std::string(pybind11::str(state[0]))); + GetLogger("Archive")->trace("State for unpickling of object of type {} = {}", + Demangle(typeid(T).name()), + std::string(pybind11::str(state[0]))); PyArchive ar(state[0]); ar & val; return val; diff --git a/libsrc/core/utils.hpp b/libsrc/core/utils.hpp index da90e1d3..f2a73578 100644 --- a/libsrc/core/utils.hpp +++ b/libsrc/core/utils.hpp @@ -2,6 +2,8 @@ #define NETGEN_CORE_UTILS_HPP #include +#include +#include #include #include @@ -56,7 +58,13 @@ namespace ngcore return ss.str(); } - + template + std::ostream& operator << (std::ostream& ost, const std::map& map) + { + for(auto& val : map) + ost << "\n" << val.first << ": " << val.second; + return ost; + } } // namespace ngcore #endif // NETGEN_CORE_UTILS_HPP diff --git a/libsrc/core/version.hpp b/libsrc/core/version.hpp index 69598716..aea50bf6 100644 --- a/libsrc/core/version.hpp +++ b/libsrc/core/version.hpp @@ -1,6 +1,7 @@ #ifndef NETGEN_CORE_VERSION_HPP #define NETGEN_CORE_VERSION_HPP +#include #include #include @@ -83,6 +84,11 @@ namespace ngcore bool operator <=(const VersionInfo& other) const { return !((*this) > other); } bool operator >=(const VersionInfo& other) const { return !((*this) < other); } }; + + inline std::ostream& operator << (std::ostream& ost, const VersionInfo& version) + { + return ost << version.to_string(); + } } // namespace ngcore #endif // NETGEN_CORE_VERSION_HPP diff --git a/tests/catch/archive.cpp b/tests/catch/archive.cpp index b3f27d49..60cd33f0 100644 --- a/tests/catch/archive.cpp +++ b/tests/catch/archive.cpp @@ -236,6 +236,18 @@ void testMultipleInheritance(Archive& in, Archive& out) } } +void testMap(Archive& in, Archive& out) +{ + map map1; + map1["netgen"] = "v6.2.1901"; + out & map1; + out.FlushBuffer(); + map map2; + in & map2; + CHECK(map2.size() == 1); + CHECK(map2["netgen"] == "v6.2.1901"); +} + void testArchive(Archive& in, Archive& out) { SECTION("Empty String") @@ -285,11 +297,14 @@ void testArchive(Archive& in, Archive& out) { testNullPtr(in, out); } + SECTION("map") + { + testMap(in, out); + } } TEST_CASE("BinaryArchive") { - SetLibraryVersion("netgen","v6.2.1811"); auto stream = make_shared(); BinaryOutArchive out(stream); BinaryInArchive in(stream); @@ -298,7 +313,6 @@ TEST_CASE("BinaryArchive") TEST_CASE("TextArchive") { - SetLibraryVersion("netgen","v6.2.1811"); auto stream = make_shared(); TextOutArchive out(stream); TextInArchive in(stream);