New function to check if two files differ: file_content_differs()
authorThomas Jarosch <thomas.jarosch@intra2net.com>
Wed, 11 Nov 2015 17:47:19 +0000 (18:47 +0100)
committerThomas Jarosch <thomas.jarosch@intra2net.com>
Wed, 11 Nov 2015 17:47:42 +0000 (18:47 +0100)
src/filefunc.cpp
src/filefunc.hxx
test/test_filefunc.cpp

index 33ef325..c061e08 100644 (file)
@@ -255,6 +255,40 @@ time_t file_mtime(const std::string& path)
 
 
 /**
+ * @brief Check if two files differ
+ *
+ *        Note: Reads the whole file into memory
+ *              if the file size is identical.
+ *
+ * @param old_filename Filename of old file
+ * @param new_filename Filename of new file
+ *
+ * @return bool True if files differ, false otherwise.
+ *              If one file does not exist, also returns true
+ */
+bool file_content_differs(const std::string &old_filename, const std::string &new_filename)
+{
+    if (I2n::file_exists(old_filename) == false ||
+        I2n::file_exists(new_filename) == false)
+        return true;
+
+    // check if size differs
+    if (I2n::file_size(old_filename) != I2n::file_size(new_filename))
+        return true;
+
+    const std::string old_content = I2n::read_file(old_filename);
+    const std::string new_content = I2n::read_file(new_filename);
+
+    // check if content differs
+    if (old_content == new_content)
+        return false;
+
+    // Differ by default (fallback)
+    return true;
+}
+
+
+/**
  * @brief reads the contents of a directory.
  * @param path the path to the directory whose contents should be read.
  * @param[out] result the resulting list of names.
index 6bab70b..acfd637 100644 (file)
@@ -146,6 +146,7 @@ protected:
 bool path_exists(const std::string& path);
 bool file_exists(const std::string& path);
 long file_size (const std::string &name);
+bool file_content_differs(const std::string &old_filename, const std::string &new_filename);
 
 time_t file_mtime(const std::string& path);
 
index 860439e..6dbf24b 100644 (file)
@@ -434,4 +434,33 @@ BOOST_AUTO_TEST_CASE(WriteFileEmptyData)
     unlink(".foobar");
 }
 
+BOOST_AUTO_TEST_CASE(FileContentDiffersIsIdentical)
+{
+    BOOST_CHECK_EQUAL( false, file_content_differs("/etc/passwd", "/etc/passwd") );
+}
+
+BOOST_AUTO_TEST_CASE(FileContentDiffersNonExistent)
+{
+    BOOST_CHECK_EQUAL( true, file_content_differs("/etc/passwd", "abc") );
+    BOOST_CHECK_EQUAL( true, file_content_differs("abc", "/etc/passwd") );
+}
+
+BOOST_AUTO_TEST_CASE(FileContentDiffersEqualSize)
+{
+    const string name1 = "file1", name2 = "file2";
+    {
+        ofstream out1(name1.c_str());
+        out1 << "abc";
+
+        ofstream out2(name2.c_str());
+        out2 << "xyz";
+    }
+
+    bool res = file_content_differs(name1, name2);
+    unlink(name1);
+    unlink(name2);
+
+    BOOST_CHECK_EQUAL( true, res );
+}
+
 BOOST_AUTO_TEST_SUITE_END()