mirror of
https://github.com/NGSolve/netgen.git
synced 2025-01-11 21:50:34 +05:00
version checks for archive, fix archive of empty string
This commit is contained in:
parent
a1847ec05f
commit
292dbcf5a0
@ -5,6 +5,6 @@ set_target_properties(ngcore PROPERTIES POSITION_INDEPENDENT_CODE ON )
|
||||
|
||||
install(TARGETS ngcore DESTINATION ${NG_INSTALL_DIR} COMPONENT netgen)
|
||||
|
||||
install(FILES ngcore.hpp archive.hpp basearchive.hpp
|
||||
install(FILES ngcore.hpp archive.hpp basearchive.hpp version.hpp
|
||||
DESTINATION ${NG_INSTALL_DIR_INCLUDE}/core COMPONENT netgen_devel
|
||||
)
|
||||
|
@ -6,16 +6,22 @@ namespace ngcore
|
||||
// BinaryOutArchive ======================================================================
|
||||
class BinaryOutArchive : public Archive
|
||||
{
|
||||
std::shared_ptr<std::ostream> fout;
|
||||
size_t ptr = 0;
|
||||
enum { BUFFERSIZE = 1024 };
|
||||
char buffer[BUFFERSIZE];
|
||||
std::shared_ptr<std::ostream> fout;
|
||||
public:
|
||||
BinaryOutArchive (std::shared_ptr<std::ostream> afout) : Archive(true), fout(afout) { ; }
|
||||
BinaryOutArchive (std::string filename)
|
||||
BinaryOutArchive(std::shared_ptr<std::ostream> afout) : Archive(true), fout(afout)
|
||||
{
|
||||
(*this) & GetLibraryVersions();
|
||||
}
|
||||
BinaryOutArchive(std::string filename)
|
||||
: BinaryOutArchive(std::make_shared<std::ofstream>(filename)) {}
|
||||
virtual ~BinaryOutArchive () { FlushBuffer(); }
|
||||
|
||||
const VersionInfo& getVersion(const std::string& library)
|
||||
{ return GetLibraryVersions()[library]; }
|
||||
|
||||
using Archive::operator&;
|
||||
virtual Archive & operator & (double & d)
|
||||
{ return Write(d); }
|
||||
@ -76,11 +82,18 @@ namespace ngcore
|
||||
// BinaryInArchive ======================================================================
|
||||
class BinaryInArchive : public Archive
|
||||
{
|
||||
std::map<std::string, VersionInfo> vinfo;
|
||||
std::shared_ptr<std::istream> fin;
|
||||
public:
|
||||
BinaryInArchive (std::shared_ptr<std::istream> afin) : Archive(false), fin(afin) { ; }
|
||||
BinaryInArchive (std::shared_ptr<std::istream> afin) : Archive(false), fin(afin)
|
||||
{
|
||||
(*this) & vinfo;
|
||||
}
|
||||
BinaryInArchive (std::string filename)
|
||||
: BinaryInArchive(std::make_shared<std::ifstream>(filename)) {}
|
||||
: BinaryInArchive(std::make_shared<std::ifstream>(filename)) { ; }
|
||||
|
||||
const VersionInfo& getVersion(const std::string& library)
|
||||
{ return vinfo[library]; }
|
||||
|
||||
using Archive::operator&;
|
||||
virtual Archive & operator & (double & d)
|
||||
@ -133,10 +146,16 @@ namespace ngcore
|
||||
{
|
||||
std::shared_ptr<std::ostream> fout;
|
||||
public:
|
||||
TextOutArchive (std::shared_ptr<std::ostream> afout) : Archive(true), fout(afout) { }
|
||||
TextOutArchive (std::shared_ptr<std::ostream> afout) : Archive(true), fout(afout)
|
||||
{
|
||||
(*this) & GetLibraryVersions();
|
||||
}
|
||||
TextOutArchive (std::string filename) :
|
||||
TextOutArchive(std::make_shared<std::ofstream>(filename.c_str())) { }
|
||||
|
||||
const VersionInfo& getVersion(const std::string& library)
|
||||
{ return GetLibraryVersions()[library]; }
|
||||
|
||||
using Archive::operator&;
|
||||
virtual Archive & operator & (double & d)
|
||||
{ *fout << d << '\n'; return *this; }
|
||||
@ -156,16 +175,22 @@ namespace ngcore
|
||||
{
|
||||
int len = str.length();
|
||||
*fout << len << '\n';
|
||||
fout->write(&str[0], len);
|
||||
*fout << '\n';
|
||||
if(len)
|
||||
{
|
||||
fout->write(&str[0], len);
|
||||
*fout << '\n';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
virtual Archive & operator & (char *& str)
|
||||
{
|
||||
int len = strlen (str);
|
||||
*fout << len << '\n';
|
||||
fout->write (&str[0], len);
|
||||
*fout << '\n';
|
||||
if(len)
|
||||
{
|
||||
fout->write (&str[0], len);
|
||||
*fout << '\n';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
@ -173,12 +198,19 @@ namespace ngcore
|
||||
// TextInArchive ======================================================================
|
||||
class TextInArchive : public Archive
|
||||
{
|
||||
std::map<std::string, VersionInfo> vinfo;
|
||||
std::shared_ptr<std::istream> fin;
|
||||
public:
|
||||
TextInArchive (std::shared_ptr<std::istream> afin) : Archive(false), fin(afin) { ; }
|
||||
TextInArchive (std::shared_ptr<std::istream> afin) : Archive(false), fin(afin)
|
||||
{
|
||||
(*this) & vinfo;
|
||||
}
|
||||
TextInArchive (std::string filename)
|
||||
: TextInArchive(std::make_shared<std::ifstream>(filename)) {}
|
||||
|
||||
const VersionInfo& getVersion(const std::string& library)
|
||||
{ return vinfo[library]; }
|
||||
|
||||
using Archive::operator&;
|
||||
virtual Archive & operator & (double & d)
|
||||
{ *fin >> d; return *this; }
|
||||
@ -201,7 +233,8 @@ namespace ngcore
|
||||
char ch;
|
||||
fin->get(ch); // '\n'
|
||||
str.resize(len);
|
||||
fin->get(&str[0], len+1, '\0');
|
||||
if(len)
|
||||
fin->get(&str[0], len+1, '\0');
|
||||
return *this;
|
||||
}
|
||||
virtual Archive & operator & (char *& str)
|
||||
@ -211,7 +244,8 @@ namespace ngcore
|
||||
char ch;
|
||||
fin->get(ch); // '\n'
|
||||
str = new char[len+1];
|
||||
fin->get(&str[0], len, '\0');
|
||||
if(len)
|
||||
fin->get(&str[0], len, '\0');
|
||||
str[len] = 0;
|
||||
return *this;
|
||||
}
|
||||
|
@ -7,6 +7,11 @@
|
||||
|
||||
namespace ngcore
|
||||
{
|
||||
std::map<std::string, VersionInfo>& GetLibraryVersions()
|
||||
{
|
||||
static std::map<std::string, VersionInfo> library_versions;
|
||||
return library_versions;
|
||||
}
|
||||
#ifdef WIN
|
||||
// windows does demangling in typeid(T).name()
|
||||
std::string demangle(const char* typeinfo) { return typeinfo; }
|
||||
|
@ -3,6 +3,10 @@
|
||||
|
||||
namespace ngcore
|
||||
{
|
||||
class VersionInfo;
|
||||
// Libraries using this archive can store their version here to implement backwards compatibility
|
||||
std::map<std::string, VersionInfo>& GetLibraryVersions();
|
||||
|
||||
class Archive;
|
||||
std::string demangle(const char* typeinfo);
|
||||
|
||||
@ -75,6 +79,7 @@ namespace ngcore
|
||||
|
||||
bool Output () { return is_output; }
|
||||
bool Input () { return !is_output; }
|
||||
virtual const VersionInfo& getVersion(const std::string& library) = 0;
|
||||
|
||||
// Pure virtual functions that have to be implemented by In-/OutArchive
|
||||
virtual Archive & operator & (double & d) = 0;
|
||||
@ -116,6 +121,29 @@ namespace ngcore
|
||||
Do(&v[0], size);
|
||||
return (*this);
|
||||
}
|
||||
template<typename T1, typename T2>
|
||||
Archive& operator& (std::map<T1, T2>& map)
|
||||
{
|
||||
if(is_output)
|
||||
{
|
||||
(*this) << size_t(map.size());
|
||||
for(auto& pair : map)
|
||||
(*this) << pair.first << pair.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t size;
|
||||
(*this) & size;
|
||||
T1 key; T2 val;
|
||||
for(size_t i = 0; i < size; i++)
|
||||
{
|
||||
T1 key; T2 val;
|
||||
(*this) & key & val;
|
||||
map[key] = val;
|
||||
}
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
// Archive arrays =====================================================
|
||||
// this functions can be overloaded in Archive implementations for more efficiency
|
||||
template <typename T>
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
@ -15,6 +16,8 @@
|
||||
#include <complex>
|
||||
|
||||
|
||||
namespace ngcore
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
inline bool likely (bool x) { return __builtin_expect((x), true); }
|
||||
inline bool unlikely (bool x) { return __builtin_expect((x), false); }
|
||||
@ -22,9 +25,11 @@
|
||||
inline bool likely (bool x) { return x; }
|
||||
inline bool unlikely (bool x) { return x; }
|
||||
#endif
|
||||
}
|
||||
|
||||
// own includes
|
||||
#include "basearchive.hpp"
|
||||
#include "version.hpp"
|
||||
#include "archive.hpp"
|
||||
|
||||
#endif // NG_CORE_HPP
|
||||
|
84
libsrc/core/version.hpp
Normal file
84
libsrc/core/version.hpp
Normal file
@ -0,0 +1,84 @@
|
||||
|
||||
namespace ngcore
|
||||
{
|
||||
class VersionInfo
|
||||
{
|
||||
private:
|
||||
size_t mayor, minor, date, commit_offset;
|
||||
std::string git_hash;
|
||||
public:
|
||||
VersionInfo() : mayor(0), minor(0), date(0), commit_offset(0), git_hash("") {}
|
||||
VersionInfo(std::string vstring)
|
||||
{
|
||||
minor = date = commit_offset = 0;
|
||||
git_hash = "";
|
||||
if(vstring.substr(0,1) == "v")
|
||||
vstring = vstring.substr(1,vstring.size()-1);
|
||||
auto dot = vstring.find(".");
|
||||
mayor = std::stoi(vstring.substr(0,dot));
|
||||
if(dot == size_t(-1)) vstring = "";
|
||||
else vstring = vstring.substr(dot+1, vstring.size()-dot-1);
|
||||
if(vstring.size())
|
||||
{
|
||||
dot = vstring.find(".");
|
||||
minor = std::stoi(vstring.substr(0,dot));
|
||||
if (dot == size_t(-1)) vstring = "";
|
||||
else vstring = vstring.substr(dot+1, vstring.size()-dot-1);
|
||||
if(vstring.size())
|
||||
{
|
||||
dot = vstring.find("-");
|
||||
date = std::stoi(vstring.substr(0,dot));
|
||||
if(dot == size_t(-1)) vstring = "";
|
||||
else vstring = vstring.substr(dot+1,vstring.size()-dot-1);
|
||||
if(vstring.size())
|
||||
{
|
||||
dot = vstring.find("-");
|
||||
commit_offset = std::stoi(vstring.substr(0,dot));
|
||||
if(dot == size_t(-1)) vstring = "";
|
||||
else vstring = vstring.substr(dot+1, vstring.size()-dot-1);
|
||||
if(vstring.size())
|
||||
git_hash = vstring;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
VersionInfo(const char* cstr) : VersionInfo(std::string(cstr)) { }
|
||||
|
||||
std::string to_string() const
|
||||
{ std::string vstring = "v" + std::to_string(mayor);
|
||||
if(minor || date || commit_offset || git_hash.size())
|
||||
{
|
||||
vstring += "." + std::to_string(minor);
|
||||
if(date || commit_offset || git_hash.size())
|
||||
{
|
||||
vstring += "." + std::to_string(date);
|
||||
if(commit_offset || git_hash.size())
|
||||
{
|
||||
vstring += "-" + std::to_string(commit_offset);
|
||||
if(git_hash.size())
|
||||
vstring += "-" + git_hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
return vstring;
|
||||
}
|
||||
bool operator <(const VersionInfo& other) const
|
||||
{
|
||||
return std::tie(mayor, minor, date, commit_offset) <
|
||||
std::tie(other.mayor, other.minor, other.date, other.commit_offset);
|
||||
}
|
||||
bool operator ==(const VersionInfo& other) const
|
||||
{
|
||||
return mayor == other.mayor && minor == other.minor && date == other.date
|
||||
&& commit_offset == other.commit_offset;
|
||||
}
|
||||
bool operator >(const VersionInfo& other) const { return other < (*this); }
|
||||
bool operator <=(const VersionInfo& other) const { return !((*this) > other); }
|
||||
bool operator >=(const VersionInfo& other) const { return !((*this) < other); }
|
||||
|
||||
void DoArchive(Archive& ar)
|
||||
{
|
||||
ar & mayor & minor & date & commit_offset & git_hash;
|
||||
}
|
||||
};
|
||||
}
|
@ -371,19 +371,17 @@ However, when r = 0, the top part becomes a point(tip) and meshing fails!
|
||||
.def(py::pickle(
|
||||
[](CSGeometry& self)
|
||||
{
|
||||
stringstream ss;
|
||||
self.Save(ss);
|
||||
cout << "pickle = " << endl << ss.str() << endl;
|
||||
return py::make_tuple(ss.str());
|
||||
auto ss = make_shared<stringstream>();
|
||||
BinaryOutArchive archive(ss);
|
||||
archive & self;
|
||||
return py::make_tuple(ss->str());
|
||||
},
|
||||
[](py::tuple state)
|
||||
{
|
||||
auto geo = make_shared<CSGeometry>();
|
||||
auto val = py::cast<string>(state[0]);
|
||||
cout << "unpickle = " << endl << val << endl;
|
||||
stringstream ss(py::cast<string>(state[0]));
|
||||
// geo->Load(ss);
|
||||
// geo->FindIdenticSurfaces(1e-8 * geo->MaxSize());
|
||||
auto ss = make_shared<stringstream> (py::cast<string>(state[0]));
|
||||
BinaryInArchive archive(ss);
|
||||
archive & (*geo);
|
||||
return geo;
|
||||
}))
|
||||
.def("Save", FunctionPointer([] (CSGeometry & self, string filename)
|
||||
|
@ -27,4 +27,5 @@ macro(add_unit_test name sources)
|
||||
endmacro()
|
||||
|
||||
add_unit_test(archive archive.cpp)
|
||||
add_unit_test(version version.cpp)
|
||||
endif(ENABLE_UNIT_TESTS)
|
||||
|
@ -203,8 +203,24 @@ void testMultipleInheritance(Archive& in, Archive& out)
|
||||
}
|
||||
}
|
||||
|
||||
void testLibraryVersion(Archive& in, Archive& out)
|
||||
{
|
||||
GetLibraryVersions()["netgen"] = "v6.2.1812";
|
||||
CHECK(in.getVersion("netgen") == "v6.2.1811");
|
||||
CHECK(out.getVersion("netgen") == "v6.2.1812");
|
||||
}
|
||||
|
||||
void testArchive(Archive& in, Archive& out)
|
||||
{
|
||||
SECTION("Empty String")
|
||||
{
|
||||
out << string("") << 1;
|
||||
out.FlushBuffer();
|
||||
string str; int i;
|
||||
in & str & i;
|
||||
CHECK(str == "");
|
||||
CHECK(i == 1);
|
||||
}
|
||||
SECTION("SharedPtr")
|
||||
{
|
||||
testSharedPointer(in, out);
|
||||
@ -226,10 +242,15 @@ void testArchive(Archive& in, Archive& out)
|
||||
{
|
||||
testNullPtr(in, out);
|
||||
}
|
||||
SECTION("Library Version")
|
||||
{
|
||||
testLibraryVersion(in,out);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("BinaryArchive")
|
||||
{
|
||||
GetLibraryVersions()["netgen"] = "v6.2.1811";
|
||||
auto stream = make_shared<stringstream>();
|
||||
BinaryOutArchive out(stream);
|
||||
BinaryInArchive in(stream);
|
||||
@ -238,6 +259,7 @@ TEST_CASE("BinaryArchive")
|
||||
|
||||
TEST_CASE("TextArchive")
|
||||
{
|
||||
GetLibraryVersions()["netgen"] = "v6.2.1811";
|
||||
auto stream = make_shared<stringstream>();
|
||||
TextOutArchive out(stream);
|
||||
TextInArchive in(stream);
|
||||
|
19
tests/catch/version.cpp
Normal file
19
tests/catch/version.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
#include "catch.hpp"
|
||||
#include <../core/ngcore.hpp>
|
||||
using namespace ngcore;
|
||||
using namespace std;
|
||||
|
||||
|
||||
TEST_CASE("Version")
|
||||
{
|
||||
VersionInfo v("v6.2.1811-3-asdf");
|
||||
CHECK(v.to_string() == "v6.2.1811-3-asdf");
|
||||
VersionInfo v2("6.2");
|
||||
CHECK(v2.to_string() == "v6.2");
|
||||
CHECK(v < "v7");
|
||||
CHECK(v >= "6.2");
|
||||
CHECK(v > "6.2.1811");
|
||||
CHECK(v < "6.2.1811-5");
|
||||
CHECK(v == "v6.2.1811-3");
|
||||
}
|
Loading…
Reference in New Issue
Block a user