#ifndef __COGAPS_ARCHIVE_H__ #define __COGAPS_ARCHIVE_H__ #include "GapsAssert.h" #include <fstream> #include <stdint.h> // flags for opening an archive #define ARCHIVE_READ std::ios::in #define ARCHIVE_WRITE (std::ios::out | std::ios::trunc) // magic number written to beginning of archive files // needs to be updated everytime the method of checkpointing changes //#define ARCHIVE_MAGIC_NUM 0xCE45D32B // v3.3.22 #define ARCHIVE_MAGIC_NUM 0xB123AA4D // v3.3.30 class Archive { public: Archive(const std::string &path, std::ios_base::openmode flags) : mStream(path.c_str(), std::ios::binary | flags) { if (flags == ARCHIVE_WRITE) { *this << static_cast<uint32_t>(ARCHIVE_MAGIC_NUM); } else // read { uint32_t magic = 0; *this >> magic; if (magic != ARCHIVE_MAGIC_NUM) { GAPS_ERROR("incompatible checkpoint file\n"); } } } ~Archive() { mStream.close(); } template<typename T> friend Archive& writeToArchive(Archive &ar, T val) { ar.mStream.write(reinterpret_cast<char*>(&val), sizeof(T)); // NOLINT return ar; } template<typename T> friend Archive& readFromArchive(Archive &ar, T &val) { ar.mStream.read(reinterpret_cast<char*>(&val), sizeof(T)); // NOLINT return ar; } // explicitly define which types can be automatically written/read // don't have C++11 and don't want to add another dependency on boost, // so no template tricks friend Archive& operator<<(Archive &ar, char val) { return writeToArchive(ar, val); } friend Archive& operator<<(Archive &ar, bool val) { return writeToArchive(ar, val); } friend Archive& operator<<(Archive &ar, int val) { return writeToArchive(ar, val); } friend Archive& operator<<(Archive &ar, unsigned val) { return writeToArchive(ar, val); } friend Archive& operator<<(Archive &ar, unsigned long val) { return writeToArchive(ar, val); } friend Archive& operator<<(Archive &ar, unsigned long long val) { return writeToArchive(ar, val); } friend Archive& operator<<(Archive &ar, int64_t val) { return writeToArchive(ar, val); } friend Archive& operator<<(Archive &ar, float val) { return writeToArchive(ar, val); } friend Archive& operator<<(Archive &ar, double val) { return writeToArchive(ar, val); } friend Archive& operator>>(Archive &ar, char &val) { return readFromArchive(ar, val); } friend Archive& operator>>(Archive &ar, bool &val) { return readFromArchive(ar, val); } friend Archive& operator>>(Archive &ar, int &val) { return readFromArchive(ar, val); } friend Archive& operator>>(Archive &ar, unsigned &val) { return readFromArchive(ar, val); } friend Archive& operator>>(Archive &ar, unsigned long &val) { return readFromArchive(ar, val); } friend Archive& operator>>(Archive &ar, unsigned long long &val) { return readFromArchive(ar, val); } friend Archive& operator>>(Archive &ar, int64_t &val) { return readFromArchive(ar, val); } friend Archive& operator>>(Archive &ar, float &val) { return readFromArchive(ar, val); } friend Archive& operator>>(Archive &ar, double &val) { return readFromArchive(ar, val); } private: std::fstream mStream; }; #endif // __COGAPS_ARCHIVE_H__