Create get_dir_size to avoid unnecessary name copying if only size needed
authorChristian Herdtweck <christian.herdtweck@intra2net.com>
Thu, 16 Mar 2017 13:13:24 +0000 (14:13 +0100)
committerThomas Jarosch <thomas.jarosch@intra2net.com>
Wed, 22 Mar 2017 10:17:15 +0000 (11:17 +0100)
src/filefunc.cpp
src/filefunc.hxx
test/test_filefunc.cpp

index e12bed4..cf5601a 100644 (file)
@@ -308,6 +308,7 @@ bool get_dir(
     std::vector< std::string >& result,
     bool include_dot_names )
 {
+    // code copied for get_dir_size; keep in sync
     DIR* dir = ::opendir( path.c_str());
     if (!dir)
     {
@@ -342,6 +343,32 @@ std::vector< std::string > get_dir(const std::string& path, bool include_dot_nam
 } // eo get_dir(const std::string&,bool)
 
 
+/**
+ * @brief count entries in directory, like get_dir(path, include_dot_names).size()
+ * @param path the path to the directory whose contents should be read.
+ * @param include_dot_names determines if dot-files should be included in the count.
+ * @return the number of entries in the directory; return -1 in case of error
+ */
+int get_dir_size(const std::string& path, bool include_dot_names)
+{
+    // code is a simplified copy of get_dir, above. Keep in sync
+    int result = 0;
+    DIR* dir = ::opendir( path.c_str());
+    if (!dir)
+        return -1;
+    struct dirent store, *entry = NULL;
+    while (readdir_r(dir, &store, &entry) == 0 && entry != NULL)
+    {
+        if (entry->d_name == NULL)
+            continue;    // should not happen
+        else if (! include_dot_names && (entry->d_name)[0] == '.')
+            continue;
+        ++result;
+    }
+    ::closedir(dir);
+    return result;
+}
+
 
 /**
  * @brief removes a file from a filesystem.
index a122ff5..b9f2d44 100644 (file)
@@ -162,6 +162,7 @@ time_t file_mtime(const std::string& path);
 
 bool get_dir(const std::string& path, std::vector< std::string >& result, bool include_dot_names= false );
 std::vector< std::string > get_dir(const std::string& path, bool include_dot_names= false );
+int get_dir_size(const std::string& path, bool include_dot_names= false );
 
 bool unlink(const std::string& path);
 
index 4d5f931..0deb521 100644 (file)
@@ -156,6 +156,7 @@ BOOST_AUTO_TEST_CASE(DirTest1)
 
     BOOST_CHECK_EQUAL( true, res );
     BOOST_CHECK( ! names.empty() );
+    BOOST_CHECK_EQUAL(I2n::get_dir_size(test_dir), names.size());
 
     BOOST_MESSAGE("Looking for " << basename(__FILE__) << " in " << test_dir);
     StringVector::iterator it = std::find( names.begin(), names.end(), basename(__FILE__));
@@ -166,6 +167,7 @@ BOOST_AUTO_TEST_CASE(DirTest1)
 
     names= get_dir(test_dir,true);
     BOOST_CHECK( ! names.empty() );
+    BOOST_CHECK_EQUAL(I2n::get_dir_size(test_dir, true), names.size());
 
     for (it= names.begin(); it!=names.end(); ++it)
     {