libi2ncommon: (tomj) added copy_file function
authorThomas Jarosch <thomas.jarosch@intra2net.com>
Thu, 10 Apr 2008 12:35:50 +0000 (12:35 +0000)
committerThomas Jarosch <thomas.jarosch@intra2net.com>
Thu, 10 Apr 2008 12:35:50 +0000 (12:35 +0000)
src/filefunc.cpp
src/filefunc.hxx
test/test_filefunc.cpp

index a00c3fe..a8d60fe 100644 (file)
@@ -441,6 +441,44 @@ bool write_file(const std::string& path, const std::string& data)
 
 
 /**
+ * Copy file in 4k blocks from source to target.
+ * Overwrites the target if it already exists.
+ *
+ * On error the target file gets removed.
+ *
+ * @param src source file
+ * @param dest target file
+ * @return true if all is ok, false on error
+ */
+bool copy_file(const std::string& src, const std::string& dest)
+{
+   std::ifstream input( src.c_str(), std::ios::in | std::ios::binary );
+   if (!input)
+      return false;
+
+   std::ofstream output( dest.c_str(), std::ios::out | std::ios::binary | std::ios::trunc);
+   if (!output)
+      return false;
+
+   char buffer[4096];
+   while (input.good())
+   {
+      input.read(buffer, sizeof(buffer));
+      output.write(buffer, input.gcount());
+
+      // Out of disc space?
+      if (!output.good())
+      {
+         output.close();
+         unlink(dest);
+         return false;
+      }
+   }
+
+   return true;
+}
+
+/**
  * @brief returns the filename part of a path (last component)
  * @param path the path.
  * @return the last component of the path.
index 9de7873..c0c01f7 100644 (file)
@@ -143,6 +143,8 @@ std::string read_file(const std::string& path);
 
 bool write_file(const std::string& path, const std::string& data);
 
+bool copy_file(const std::string& src, const std::string& dest);
+
 std::string basename(const std::string& path);
 
 std::string dirname(const std::string& path);
index eef4cde..862f926 100644 (file)
@@ -14,6 +14,7 @@
 #include <list>
 #include <iostream>
 #include <iomanip>
+#include <fstream>
 #include <sstream>
 #include <algorithm>
 
@@ -30,7 +31,7 @@
 #define DOUT(msg) do {} while (0)
 #endif
 
-
+using namespace std;
 using namespace I2n;
 
 using namespace CppUnit;
@@ -53,7 +54,9 @@ class TestFileFunc : public TestFixture
    CPPUNIT_TEST(TestUserAndGroupStuff1);
    CPPUNIT_TEST(TestFileModes1);
    CPPUNIT_TEST(TestPidOf1);
-
+   CPPUNIT_TEST(TestCopyFileSourceFail);
+   CPPUNIT_TEST(TestCopyFileDestFail);
+   CPPUNIT_TEST(TestCopyFileOk);
 
    CPPUNIT_TEST_SUITE_END();
 
@@ -264,8 +267,48 @@ public:
       CPPUNIT_ASSERT( pos1 != pid_list.end() );
    } // eo TestPidOf1()
 
+   void TestCopyFileSourceFail()
+   {
+      bool res = copy_file("does not exist", "destination");
+      CPPUNIT_ASSERT_EQUAL( false, res );
+   }
+
+   void TestCopyFileDestFail()
+   {
+      bool res = copy_file("/etc/HOSTNAME", "/proc/not/writable");
+      CPPUNIT_ASSERT_EQUAL( false, res );
+   }
+
+   void TestCopyFileOk()
+   {
+      string input = "copy_source";
+      string data = "test";
+
+      long input_size = 0;
+      ofstream finput(input.c_str());
+      if (finput)
+      {
+         finput << data;
+         finput.close();
+         input_size = file_size(input);
+      }
 
+      string output = "copy_dest";
+      long output_size = 0;
+      bool res = copy_file(input, output);
+      if (res)
+      {
+         output_size = file_size(output);
+      }
+      unlink(input);
+      unlink(output);
+
+      bool size_is_zero = output_size == 0 ? true : false;
 
+      CPPUNIT_ASSERT_EQUAL( true, res );
+      CPPUNIT_ASSERT_EQUAL( input_size, output_size );
+      CPPUNIT_ASSERT_EQUAL( false, size_is_zero );
+   }
 }; // eo class TestFileFunc
 
 CPPUNIT_TEST_SUITE_REGISTRATION(TestFileFunc);