netgen/libsrc/core/archive.hpp

270 lines
7.7 KiB
C++
Raw Normal View History

2018-11-29 22:35:30 +05:00
#ifndef NG_ARCHIVE_HPP
#define NG_ARCHIVE_HPP
namespace ngcore
{
// BinaryOutArchive ======================================================================
2018-12-07 17:08:00 +05:00
class NGCORE_API BinaryOutArchive : public Archive
2018-11-29 22:35:30 +05:00
{
size_t ptr = 0;
enum { BUFFERSIZE = 1024 };
char buffer[BUFFERSIZE];
std::shared_ptr<std::ostream> fout;
2018-11-29 22:35:30 +05:00
public:
BinaryOutArchive(std::shared_ptr<std::ostream> afout) : Archive(true), fout(afout)
{
(*this) & GetLibraryVersions();
}
BinaryOutArchive(std::string filename)
2018-11-29 22:35:30 +05:00
: BinaryOutArchive(std::make_shared<std::ofstream>(filename)) {}
virtual ~BinaryOutArchive () { FlushBuffer(); }
const VersionInfo& getVersion(const std::string& library)
{ return GetLibraryVersions()[library]; }
using Archive::operator&;
2018-11-29 22:35:30 +05:00
virtual Archive & operator & (double & d)
{ return Write(d); }
virtual Archive & operator & (int & i)
{ return Write(i); }
virtual Archive & operator & (short & i)
{ return Write(i); }
virtual Archive & operator & (long & i)
{ return Write(i); }
virtual Archive & operator & (size_t & i)
{ return Write(i); }
virtual Archive & operator & (unsigned char & i)
{ return Write(i); }
virtual Archive & operator & (bool & b)
{ return Write(b); }
virtual Archive & operator & (std::string & str)
{
int len = str.length();
2018-12-06 21:53:44 +05:00
(*this) & len;
FlushBuffer();
if(len)
fout->write (&str[0], len);
2018-11-29 22:35:30 +05:00
return *this;
}
virtual Archive & operator & (char *& str)
{
2018-12-06 21:53:44 +05:00
long len = str ? strlen (str) : -1;
(*this) & len;
FlushBuffer();
if(len > 0)
fout->write (&str[0], len);
2018-11-29 22:35:30 +05:00
return *this;
}
void FlushBuffer()
{
if (ptr > 0)
{
fout->write(&buffer[0], ptr);
ptr = 0;
}
}
private:
template <typename T>
Archive & Write (T x)
{
if (unlikely(ptr > BUFFERSIZE-sizeof(T)))
{
fout->write(&buffer[0], ptr);
* (T*) (&buffer[0]) = x;
ptr = sizeof(T);
return *this;
}
* (T*) (&buffer[ptr]) = x;
ptr += sizeof(T);
return *this;
}
};
// BinaryInArchive ======================================================================
2018-12-07 17:08:00 +05:00
class NGCORE_API BinaryInArchive : public Archive
2018-11-29 22:35:30 +05:00
{
std::map<std::string, VersionInfo> vinfo;
2018-11-29 22:35:30 +05:00
std::shared_ptr<std::istream> fin;
public:
BinaryInArchive (std::shared_ptr<std::istream> afin) : Archive(false), fin(afin)
{
(*this) & vinfo;
}
2018-11-29 22:35:30 +05:00
BinaryInArchive (std::string filename)
: BinaryInArchive(std::make_shared<std::ifstream>(filename)) { ; }
const VersionInfo& getVersion(const std::string& library)
{ return vinfo[library]; }
2018-11-29 22:35:30 +05:00
using Archive::operator&;
2018-11-29 22:35:30 +05:00
virtual Archive & operator & (double & d)
{ Read(d); return *this; }
virtual Archive & operator & (int & i)
{ Read(i); return *this; }
virtual Archive & operator & (short & i)
{ Read(i); return *this; }
virtual Archive & operator & (long & i)
{ Read(i); return *this; }
virtual Archive & operator & (size_t & i)
{ Read(i); return *this; }
virtual Archive & operator & (unsigned char & i)
{ Read(i); return *this; }
virtual Archive & operator & (bool & b)
{ Read(b); return *this; }
virtual Archive & operator & (std::string & str)
{
int len;
2018-12-06 21:53:44 +05:00
(*this) & len;
2018-11-29 22:35:30 +05:00
str.resize(len);
2018-12-06 21:53:44 +05:00
if(len)
fin->read(&str[0], len);
2018-11-29 22:35:30 +05:00
return *this;
}
virtual Archive & operator & (char *& str)
{
2018-12-06 21:53:44 +05:00
long len;
(*this) & len;
if(len == -1)
str = nullptr;
else
{
str = new char[len+1];
fin->read(&str[0], len);
str[len] = '\0';
}
2018-11-29 22:35:30 +05:00
return *this;
}
virtual Archive & Do (double * d, size_t n)
{ fin->read(reinterpret_cast<char*>(d), n*sizeof(double)); return *this; }
virtual Archive & Do (int * i, size_t n)
{ fin->read(reinterpret_cast<char*>(i), n*sizeof(int)); return *this; }
virtual Archive & Do (size_t * i, size_t n)
{ fin->read(reinterpret_cast<char*>(i), n*sizeof(size_t)); return *this; }
private:
template<typename T>
inline void Read(T& val)
{ fin->read(reinterpret_cast<char*>(&val), sizeof(T)); }
};
// TextOutArchive ======================================================================
2018-12-07 17:08:00 +05:00
class NGCORE_API TextOutArchive : public Archive
2018-11-29 22:35:30 +05:00
{
std::shared_ptr<std::ostream> fout;
public:
TextOutArchive (std::shared_ptr<std::ostream> afout) : Archive(true), fout(afout)
{
(*this) & GetLibraryVersions();
}
2018-11-29 22:35:30 +05:00
TextOutArchive (std::string filename) :
TextOutArchive(std::make_shared<std::ofstream>(filename.c_str())) { }
const VersionInfo& getVersion(const std::string& library)
{ return GetLibraryVersions()[library]; }
2018-11-29 22:35:30 +05:00
using Archive::operator&;
virtual Archive & operator & (double & d)
{ *fout << d << '\n'; return *this; }
virtual Archive & operator & (int & i)
{ *fout << i << '\n'; return *this; }
virtual Archive & operator & (short & i)
{ *fout << i << '\n'; return *this; }
virtual Archive & operator & (long & i)
{ *fout << i << '\n'; return *this; }
virtual Archive & operator & (size_t & i)
{ *fout << i << '\n'; return *this; }
virtual Archive & operator & (unsigned char & i)
{ *fout << int(i) << '\n'; return *this; }
virtual Archive & operator & (bool & b)
{ *fout << (b ? 't' : 'f') << '\n'; return *this; }
virtual Archive & operator & (std::string & str)
{
int len = str.length();
*fout << len << '\n';
if(len)
{
fout->write(&str[0], len);
*fout << '\n';
}
2018-11-29 22:35:30 +05:00
return *this;
}
virtual Archive & operator & (char *& str)
{
2018-12-06 21:53:44 +05:00
long len = str ? strlen (str) : -1;
*this & len;
if(len > 0)
{
fout->write (&str[0], len);
*fout << '\n';
}
2018-11-29 22:35:30 +05:00
return *this;
}
};
// TextInArchive ======================================================================
2018-12-07 17:08:00 +05:00
class NGCORE_API TextInArchive : public Archive
2018-11-29 22:35:30 +05:00
{
std::map<std::string, VersionInfo> vinfo;
2018-11-29 22:35:30 +05:00
std::shared_ptr<std::istream> fin;
public:
TextInArchive (std::shared_ptr<std::istream> afin) : Archive(false), fin(afin)
{
(*this) & vinfo;
}
2018-11-29 22:35:30 +05:00
TextInArchive (std::string filename)
: TextInArchive(std::make_shared<std::ifstream>(filename)) {}
const VersionInfo& getVersion(const std::string& library)
{ return vinfo[library]; }
2018-11-29 22:35:30 +05:00
using Archive::operator&;
virtual Archive & operator & (double & d)
{ *fin >> d; return *this; }
virtual Archive & operator & (int & i)
{ *fin >> i; return *this; }
virtual Archive & operator & (short & i)
{ *fin >> i; return *this; }
virtual Archive & operator & (long & i)
{ *fin >> i; return *this; }
virtual Archive & operator & (size_t & i)
{ *fin >> i; return *this; }
virtual Archive & operator & (unsigned char & i)
{ int _i; *fin >> _i; i = _i; return *this; }
virtual Archive & operator & (bool & b)
{ char c; *fin >> c; b = (c=='t'); return *this; }
virtual Archive & operator & (std::string & str)
{
int len;
*fin >> len;
char ch;
fin->get(ch); // '\n'
str.resize(len);
if(len)
fin->get(&str[0], len+1, '\0');
2018-11-29 22:35:30 +05:00
return *this;
}
virtual Archive & operator & (char *& str)
{
2018-12-06 21:53:44 +05:00
long len;
(*this) & len;
2018-11-29 22:35:30 +05:00
char ch;
2018-12-06 21:53:44 +05:00
if(len == -1)
{
str = nullptr;
return (*this);
}
2018-11-29 22:35:30 +05:00
str = new char[len+1];
if(len)
2018-12-06 21:53:44 +05:00
{
fin->get(ch); // \n
fin->get(&str[0], len+1, '\0');
}
str[len] = '\0';
2018-11-29 22:35:30 +05:00
return *this;
}
};
}
#endif // NG_ARCHIVE_HPP