From: Sam Moore Date: Wed, 26 Mar 2014 10:23:11 +0000 (+0800) Subject: Implement document saving and loading X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=commitdiff_plain;h=428f1eb86a616d95dbb72ff08a3d09771d5c47e6 Implement document saving and loading Also implemented a tester to test it doesn't explode. We should set this up to make replacing main() easy. --- diff --git a/.gitignore b/.gitignore index f533957..82affd5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.o *.d *~ +*.ipdf diff --git a/src/common.h b/src/common.h index 47e0329..5536f75 100644 --- a/src/common.h +++ b/src/common.h @@ -1,7 +1,16 @@ -#include +// C++ STD includes #include #include #include #include + +// C includes +#include +#include +#include +#include +#include + +// Custom includes #include "log.h" diff --git a/src/document.cpp b/src/document.cpp index 99e429e..3c1a4ab 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1,14 +1,63 @@ #include "document.h" +#include + using namespace IPDF; using namespace std; +void Document::Save(const string & filename) +{ + Debug("Saving document to file \"%s\"...", filename.c_str()); + FILE * file = fopen(filename.c_str(), "w"); + if (file == NULL) + Fatal("Couldn't open file \"%s\" - %s", filename.c_str(), strerror(errno)); + + size_t written; + Debug("Number of objects (%u)...", ObjectCount()); + written = fwrite(&m_count, sizeof(m_count), 1, file); + if (written != 1) + Fatal("Failed to write number of objects!"); + + Debug("Object bounds..."); + written = fwrite(m_objects.bounds.data(), sizeof(Rect), m_objects.bounds.size(), file); + if (written != ObjectCount()) + Fatal("Only wrote %u objects!", written); + + int err = fclose(file); + if (err != 0) + Fatal("Failed to close file \"%s\" - %s", filename.c_str(), strerror(err)); + + Debug("Successfully saved %u objects to \"%s\"", ObjectCount(), filename.c_str()); +} + void Document::Load(const string & filename) { m_objects.bounds.clear(); m_count = 0; if (filename == "") + { + Debug("Loaded empty document."); return; + } + Debug("Loading document from file \"%s\"", filename.c_str()); + FILE * file = fopen(filename.c_str(), "r"); + if (file == NULL) + Fatal("Couldn't open file \"%s\"", filename.c_str(), strerror(errno)); + + size_t read; + read = fread(&m_count, sizeof(m_count), 1, file); + if (read != 1) + Fatal("Failed to read number of objects!"); + Debug("Number of objects: %u", ObjectCount()); + + m_objects.bounds.resize(ObjectCount()); + + Debug("Object bounds..."); + read = fread(m_objects.bounds.data(), sizeof(Rect), m_objects.bounds.size(), file); + if (read != ObjectCount()) + Fatal("Only read %u objects!", read); + + Debug("Successfully loaded %u objects from \"%s\"", ObjectCount(), filename.c_str()); } void Document::Add(Real x, Real y, Real w, Real h) @@ -16,3 +65,17 @@ void Document::Add(Real x, Real y, Real w, Real h) m_objects.bounds.push_back(Rect(x, y, w, h)); m_count++; } + +void Document::DebugDumpObjects() +{ + Debug("Objects for Document %p are:", this); + for (unsigned id = 0; id < ObjectCount(); ++id) + { + Debug("%u.\t%s", id, m_objects.bounds[id].Str().c_str()); + } +} + +bool Document::operator==(const Document & equ) const +{ + return (ObjectCount() == equ.ObjectCount() && memcmp(m_objects.bounds.data(), equ.m_objects.bounds.data(), ObjectCount() * sizeof(Rect)) == 0); +} diff --git a/src/document.h b/src/document.h index 71f6d38..ffb761d 100644 --- a/src/document.h +++ b/src/document.h @@ -8,13 +8,18 @@ namespace IPDF class Document { public: - Document() : m_objects(), m_count(0) {Load();} + Document(const std::string & filename = "") : m_objects(), m_count(0) {Load(filename);} virtual ~Document() {} void Load(const std::string & filename = ""); + void Save(const std::string & filename); void Add(Real x, Real y, Real w, Real h); + void DebugDumpObjects(); - unsigned ObjectCount() {return m_count;} + unsigned ObjectCount() const {return m_count;} + + bool operator==(const Document & equ) const; + bool operator!=(const Document & equ) const {return !(this->operator==(equ));} private: friend class View; diff --git a/src/ipdf.h b/src/ipdf.h index 0264d96..e150088 100644 --- a/src/ipdf.h +++ b/src/ipdf.h @@ -8,12 +8,17 @@ namespace IPDF typedef float Real; inline float RealToFloat(Real r) {return r;} + inline Real Random(Real max=1, Real min=0) + { + return min + (max-min) * ((Real)(rand() % (int)1e6) / 1e6); + } typedef unsigned ObjectID; struct Rect { Real x; Real y; Real w; Real h; + Rect() = default; // Needed so we can fread/fwrite this struct Rect(Real _x, Real _y, Real _w, Real _h) : x(_x), y(_y), w(_w), h(_h) {} std::string Str() { diff --git a/src/tests/saveload.cpp b/src/tests/saveload.cpp new file mode 100644 index 0000000..a2d58cb --- /dev/null +++ b/src/tests/saveload.cpp @@ -0,0 +1,32 @@ +#include "../common.h" + +#include "../document.h" +#include "../view.h" + +using namespace std; +using namespace IPDF; + +unsigned test_objects = 4; + +int main(int argc, char ** argv) +{ + srand(time(NULL)); + Document doc; + for (unsigned id = 0; id < test_objects; ++id) + { + doc.Add(Random(), Random(), Random(), Random()); + } + doc.Save("test.ipdf"); + + Document equ("test.ipdf"); + //doc.Add(Random(), Random(), Random(), Random()); + if (doc != equ || equ != doc) + { + Error("Loaded document is not equivelant to saved document!"); + doc.DebugDumpObjects(); + equ.DebugDumpObjects(); + } + + + return 0; +}