#include #include #include "UnitTest++.h" #include "test_utils.hh" #include "geners/Record.hh" #include "geners/Reference.hh" #include "geners/StringArchive.hh" #include "geners/BinaryFileArchive.hh" #include "geners/MultiFileArchive.hh" #include "geners/arrayIO.hh" #define DIM 5 #define NPOINTS 50 using namespace gs; using namespace std; namespace { class Persistent2 { public: inline Persistent2(int n=0) : n_(n) {} inline bool operator==(const Persistent2& r) const {return n_ == r.n_;} inline bool operator!=(const Persistent2& r) const {return !(*this == r);} inline Persistent2& operator+=(const int& r) { n_ += r; return *this; } inline ClassId classId() const {return ClassId(*this);} inline bool write(std::ostream& os) const { write_pod(os, n_); return !os.bad() && !os.fail(); } static inline const char* classname() {return "gs::test::Persistent2";} static inline unsigned version() {return 1;} static inline Persistent2* read(const ClassId& id, std::istream& in) { assert(id == ClassId::makeId()); int n; read_pod(in, &n); if (in.fail()) throw gs::IOReadFailure("In Persistent2::read: " "input stream failure"); else return new Persistent2(n); } private: int n_; }; void test_archive(AbsArchive& ar, const bool readStuff=true) { typedef CPP11_array Point; typedef CPP11_array Point2; CHECK(ar.isOpen()); if (readStuff) CHECK(ar.isReadable()); CHECK(ar.isWritable()); // Create a table of objects std::vector data; Point location; for (unsigned i=0; i(test_rng()*1000000)); data.push_back(location); } CHECK(data[0] != data[1] || data[0] != data[2]); // Write out the table of objects ar << Record(data, "name1", "category1"); for (unsigned i=0; i(test_rng()*1000000)); data.push_back(location); } ArchiveRecord > rto( Record(data, "name1", "category1")); ar << rto; // Create a table of PODs std::vector data2; Point2 datum; for (unsigned i=0; i > rtp( Record(data2, "name2", "category2")); ar << rtp; // Duplicate some records in another archive StringArchive dup; if (readStuff && ar.isReadable()) { ar.copyItem(rto.id(), &dup, "hren", "blin"); ar.copyItem(rtp.id(), &dup); } // Write out a POD unsigned mynumber = 12345; ar << Record(mynumber, "my number", "who cares"); // Write out an archive StringArchive sa; sa << Record(mynumber, "clap", "dup"); ar << Record(sa, "my archive", "yok"); if (readStuff) { const std::vector& cats = ar.allCategories(); CHECK_EQUAL(4U, cats.size()); } // Read back the archive if (readStuff) { Reference ref(ar, "my archive", "yok"); CHECK(ref.unique()); CPP11_auto_ptr psa = ref.get(0); CHECK(sa == *psa); Reference ref4(*psa, "clap", "dup"); unsigned dummy = 0; ref4.restore(0, &dummy); CHECK_EQUAL(mynumber, dummy); } // Read back the table of PODs and check for identity // with what was written if (readStuff) { std::vector read2; Reference >( ar, "name2", "category2").restore(0, &read2); CHECK(data2 == read2); if (ar.isReadable()) { std::vector read3; Reference >( dup, "name2", "category2").restore(0, &read3); CHECK(data2 == read3); } } // Read back a pod if (readStuff) { Reference ref4(ar, "my number", "who cares"); unsigned dummy = 0; ref4.restore(0, &dummy); CHECK_EQUAL(mynumber, dummy); CPP11_auto_ptr uns2 = Reference( ar, "my number", "who cares").get(0); CHECK_EQUAL(mynumber, *uns2); } // Write out a vector of PODs std::vector vecd; for (unsigned i=0; i veco; for (unsigned i=0; i(test_rng()*1000000))); ar << Record(veco, "my vector 2", "duh"); // Write out a copy of a string ar << ValueRecord(std::string("message 1"), "some message", "uh"); // Read back and check for identity with what was written if (readStuff) { Reference > ref(ar, "name1", "category1"); CHECK(ref.size() == 2); std::vector read; ref.restore(0, &read); CHECK(data != read); ref.restore(1, &read); CHECK(data == read); CPP11_auto_ptr > tmp = ref.get(1); CHECK(data == *tmp); if (ar.isReadable()) { Reference > copyref(dup, "hren", "blin"); CHECK(copyref.unique()); CPP11_auto_ptr > copytmp = copyref.get(0); CHECK(data == *copytmp); } // Read back the vector of PODs std::vector haha; Reference >(ar, "my vector", 0).restore( 0, &haha); CHECK(haha == vecd); // Read back the vector of objects CPP11_auto_ptr > rv = Reference >( ar, "my vector 2", "duh").get(0); CHECK(*rv == veco); // Read back the string message Reference sref(ar, "some message", "uh"); std::string rb; sref.restore(0, &rb); CHECK(rb == std::string("message 1")); } } TEST(ArchiveIO_string) { StringArchive ar("Test Archive"); test_archive(ar); const std::string& st(ar.str()); CHECK_EQUAL(st.size(), ar.dataSize()); std::ostringstream os; write_item(os, ar); std::istringstream is(os.str()); ClassId myid(is, 1); CPP11_auto_ptr ar2(StringArchive::read(myid, is)); CHECK(ar2.get()); CHECK(ar == *ar2); } TEST(ArchiveIO_binary) { BinaryFileArchive ar("archive", "w+:cat=i", "binary file archive test"); test_archive(ar); ar.flush(); BinaryFileArchive ar2("archive", "r"); const unsigned long long nItems = ar.size(); CHECK_EQUAL(nItems, ar2.size()); const unsigned long long offset = 1ULL; for (unsigned long long i=offset; i