Implement document saving and loading
authorSam Moore <matches@ucc.asn.au>
Wed, 26 Mar 2014 10:23:11 +0000 (18:23 +0800)
committerSam Moore <matches@ucc.asn.au>
Wed, 26 Mar 2014 10:23:11 +0000 (18:23 +0800)
Also implemented a tester to test it doesn't explode.

We should set this up to make replacing main() easy.

.gitignore
src/common.h
src/document.cpp
src/document.h
src/ipdf.h
src/tests/saveload.cpp [new file with mode: 0644]

index f533957..82affd5 100644 (file)
@@ -1,3 +1,4 @@
 *.o
 *.d
 *~
+*.ipdf
index 47e0329..5536f75 100644 (file)
@@ -1,7 +1,16 @@
-#include <cstdlib>
+// C++ STD includes
 #include <iostream>
 #include <vector>
 #include <string>
 #include <sstream>
 
+
+// C includes
+#include <cstdlib>
+#include <cstring>
+#include <cerrno>
+#include <cstdio>
+#include <ctime>
+
+// Custom includes
 #include "log.h"
index 99e429e..3c1a4ab 100644 (file)
@@ -1,14 +1,63 @@
 #include "document.h"
 
+#include <cstdio>
+
 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);
+}
index 71f6d38..ffb761d 100644 (file)
@@ -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;
index 0264d96..e150088 100644 (file)
@@ -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 (file)
index 0000000..a2d58cb
--- /dev/null
@@ -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;
+}

UCC git Repository :: git.ucc.asn.au