From 6569b97d7200321198cf0d7f25f9e5999830b6cc Mon Sep 17 00:00:00 2001 From: Christian Herdtweck Date: Thu, 16 Mar 2017 14:13:24 +0100 Subject: [PATCH] Create get_dir_size to avoid unnecessary name copying if only size needed --- src/filefunc.cpp | 27 +++++++++++++++++++++++++++ src/filefunc.hxx | 1 + test/test_filefunc.cpp | 2 ++ 3 files changed, 30 insertions(+), 0 deletions(-) diff --git a/src/filefunc.cpp b/src/filefunc.cpp index e12bed4..cf5601a 100644 --- a/src/filefunc.cpp +++ b/src/filefunc.cpp @@ -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. diff --git a/src/filefunc.hxx b/src/filefunc.hxx index a122ff5..b9f2d44 100644 --- a/src/filefunc.hxx +++ b/src/filefunc.hxx @@ -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); diff --git a/test/test_filefunc.cpp b/test/test_filefunc.cpp index 4d5f931..0deb521 100644 --- a/test/test_filefunc.cpp +++ b/test/test_filefunc.cpp @@ -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) { -- 1.7.1