summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Ohly <patrick.ohly@intel.com>2010-05-03 10:15:38 +0200
committerPatrick Ohly <patrick.ohly@intel.com>2010-05-04 09:39:19 +0200
commit50101688df77ac58e5f8985a55a83c9b331f932c (patch)
treeffc5955bb4133babbc272d84410654321c985cfd
parent614423158999eeaf49403aebbf682bdd63d54070 (diff)
DataBlob: abstract access to chunks of data
The goal of the DataBlob base class is encapsulating read/write access to permanent data storage *on demand*. Comparing it to files, it is more like a path name than a file handle. boost::shared_ptr are used a) because it automates deletion of the actual data streams and b) some implementations of DataBlob might have to share access to these instances. One possible implementation (included in this patch) is indeed a plain file. It writes into a temporary file and only renames it to the final path name on success, which emulates the behavior of the FileConfigNode. The actual implementation of this renaming was moved into a separate class, the SafeOstream. Another (to be added later) is a chunk of data inside a larger file. This is needed for embedding different .ini style files inside one large text file, as required for MBC #1208).
-rw-r--r--src/syncevo/DataBlob.h63
-rw-r--r--src/syncevo/FileDataBlob.cpp71
-rw-r--r--src/syncevo/FileDataBlob.h61
-rw-r--r--src/syncevo/Makefile.am7
-rw-r--r--src/syncevo/SafeOstream.cpp51
-rw-r--r--src/syncevo/SafeOstream.h56
6 files changed, 309 insertions, 0 deletions
diff --git a/src/syncevo/DataBlob.h b/src/syncevo/DataBlob.h
new file mode 100644
index 00000000..258860a6
--- /dev/null
+++ b/src/syncevo/DataBlob.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008-2009 Patrick Ohly <patrick.ohly@gmx.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef INCL_EVOLUTION_DATA_BLOB
+# define INCL_EVOLUTION_DATA_BLOB
+
+#include <iostream>
+#include <boost/shared_ptr.hpp>
+
+#include <syncevo/declarations.h>
+SE_BEGIN_CXX
+
+/**
+ * Abstract base class for a chunk of data.
+ * Can be opened for reading and writing.
+ * Meant to be used for plain files and
+ * for sections inside a larger file.
+ */
+class DataBlob
+{
+ public:
+ virtual ~DataBlob() {}
+
+ /**
+ * Create stream for writing data.
+ * Always overwrites old data.
+ */
+ virtual boost::shared_ptr<std::ostream> write() = 0;
+
+ /**
+ * Create stream for reading data.
+ */
+ virtual boost::shared_ptr<std::istream> read() = 0;
+
+ /** some kind of user visible name for the data */
+ virtual std::string getName() const = 0;
+
+ /** true if the data exists already */
+ virtual bool exists() const = 0;
+
+ /** true if the data is read-only and write() will fail */
+ virtual bool isReadonly() const = 0;
+};
+
+SE_END_CXX
+
+#endif // INCL_EVOLUTION_DATA_BLOB
diff --git a/src/syncevo/FileDataBlob.cpp b/src/syncevo/FileDataBlob.cpp
new file mode 100644
index 00000000..e0dc2c00
--- /dev/null
+++ b/src/syncevo/FileDataBlob.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008-2009 Patrick Ohly <patrick.ohly@gmx.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <syncevo/FileDataBlob.h>
+#include <syncevo/SafeOstream.h>
+#include <syncevo/util.h>
+
+#include <unistd.h>
+
+#include <syncevo/declarations.h>
+SE_BEGIN_CXX
+
+FileDataBlob::FileDataBlob(const std::string &path, const std::string &fileName, bool readonly) :
+ m_path(path),
+ m_fileName(fileName),
+ m_readonly(readonly)
+{
+}
+
+FileDataBlob::FileDataBlob(const std::string &fullpath, bool readonly) :
+ m_readonly(readonly)
+{
+ splitPath(fullpath, m_path, m_fileName);
+}
+
+boost::shared_ptr<std::ostream> FileDataBlob::write()
+{
+ if (m_readonly) {
+ SE_THROW(getName() + ": internal error: attempt to write read-only FileDataBlob");
+ }
+
+ mkdir_p(m_path);
+
+ boost::shared_ptr<std::ostream> file(new SafeOstream(getName()));
+ return file;
+}
+
+boost::shared_ptr<std::istream> FileDataBlob::read()
+{
+ boost::shared_ptr<std::istream> file(new std::ifstream(getName().c_str()));
+ return file;
+}
+
+std::string FileDataBlob::getName() const
+{
+ return m_path + "/" + m_fileName;
+}
+
+bool FileDataBlob::exists() const
+{
+ std::string fullname = getName();
+ return !access(fullname.c_str(), F_OK);
+}
+
+SE_END_CXX
diff --git a/src/syncevo/FileDataBlob.h b/src/syncevo/FileDataBlob.h
new file mode 100644
index 00000000..c889902d
--- /dev/null
+++ b/src/syncevo/FileDataBlob.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2008-2009 Patrick Ohly <patrick.ohly@gmx.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef INCL_EVOLUTION_FILE_DATA_BLOB
+# define INCL_EVOLUTION_FILE_DATA_BLOB
+
+#include <syncevo/DataBlob.h>
+#include <string>
+
+#include <syncevo/declarations.h>
+SE_BEGIN_CXX
+
+/**
+ * Abstract base class for a chunk of data.
+ * Can be opened for reading and writing.
+ * Meant to be used for plain files and
+ * for sections inside a larger file.
+ */
+class FileDataBlob : public DataBlob
+{
+ std::string m_path;
+ std::string m_fileName;
+ bool m_readonly;
+
+ public:
+ /**
+ * @param path directory name
+ * @param fileName name of file inside that directory
+ * @param readonly do not create or write file, it must exist;
+ * write() will throw an exception
+ */
+ FileDataBlob(const std::string &path, const std::string &fileName, bool readonly);
+ FileDataBlob(const std::string &fullpath, bool readonly);
+
+ boost::shared_ptr<std::ostream> write();
+ boost::shared_ptr<std::istream> read();
+
+ virtual std::string getName() const;
+ virtual bool exists() const;
+ virtual bool isReadonly() const { return m_readonly; }
+};
+
+SE_END_CXX
+
+#endif // INCL_EVOLUTION_FILE_DATA_BLOB
diff --git a/src/syncevo/Makefile.am b/src/syncevo/Makefile.am
index a8a7880a..989d2363 100644
--- a/src/syncevo/Makefile.am
+++ b/src/syncevo/Makefile.am
@@ -83,6 +83,13 @@ SYNCEVOLUTION_SOURCES = \
FileConfigNode.h \
FileConfigNode.cpp \
\
+ DataBlob.h \
+ FileDataBlob.h \
+ FileDataBlob.cpp \
+ \
+ SafeOstream.h \
+ SafeOstream.cpp \
+ \
FileConfigTree.h \
FileConfigTree.cpp \
\
diff --git a/src/syncevo/SafeOstream.cpp b/src/syncevo/SafeOstream.cpp
new file mode 100644
index 00000000..cde64f9a
--- /dev/null
+++ b/src/syncevo/SafeOstream.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008-2009 Patrick Ohly <patrick.ohly@gmx.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <syncevo/SafeOstream.h>
+#include <syncevo/SyncContext.h>
+
+#include <syncevo/declarations.h>
+SE_BEGIN_CXX
+
+SafeOstream::SafeOstream(const std::string filename) :
+ m_filename(filename)
+{
+ size_t pos = filename.rfind('/');
+ if (pos == filename.npos) {
+ m_tmpFilename = ".#";
+ m_tmpFilename += filename;
+ } else {
+ m_tmpFilename.assign(filename, 0, pos + 1);
+ m_tmpFilename += ".#";
+ m_tmpFilename += filename.substr(pos + 1);
+ }
+ open(m_tmpFilename.c_str());
+}
+
+SafeOstream::~SafeOstream()
+{
+ close();
+ if (bad() ||
+ rename(m_tmpFilename.c_str(), m_filename.c_str())) {
+ SyncContext::throwError(m_tmpFilename, errno);
+ }
+}
+
+SE_END_CXX
+
diff --git a/src/syncevo/SafeOstream.h b/src/syncevo/SafeOstream.h
new file mode 100644
index 00000000..3488eab6
--- /dev/null
+++ b/src/syncevo/SafeOstream.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008-2009 Patrick Ohly <patrick.ohly@gmx.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef INCL_EVOLUTION_SAFE_OSTREAM
+# define INCL_EVOLUTION_SAFE_OSTREAM
+
+#include <fstream>
+#include <string>
+
+#include <syncevo/declarations.h>
+SE_BEGIN_CXX
+
+/**
+ * Writes into temporary file (.# prefix) first, then renames to real
+ * file only when no error encountered at the time of deleting the
+ * instance. Once instantiated, the only way to safe the content of the
+ * real file is to set the "fail" bit. In that sense it is similar to
+ * instantiating a normal ofstream, which would directly overwrite
+ * the file at creation time.
+ */
+class SafeOstream : public std::ofstream
+{
+ std::string m_filename;
+ std::string m_tmpFilename;
+
+ public:
+ /**
+ * @param filename real filename, without the .# prefix
+ */
+ SafeOstream(const std::string filename);
+
+ /**
+ * on success, rename file
+ */
+ ~SafeOstream();
+};
+
+SE_END_CXX
+
+#endif // INCL_EVOLUTION_SAFE_OSTREAM