Function to compute the total size of the files in a directory

We need this for the diagnostic mode but it can be used by others.
Did not see test for GetFileSize() so added them

BUG=none
TEST=ut included


Review URL: http://codereview.chromium.org/1220001

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42540 0039d316-1c4b-4281-b951-d872f2087c98


CrOS-Libchrome-Original-Commit: c2c132c637874d6d3104293791b15b38da58bfc9
diff --git a/base/file_util.cc b/base/file_util.cc
index b10cd0b..d2e6575 100644
--- a/base/file_util.cc
+++ b/base/file_util.cc
@@ -268,6 +268,23 @@
   return true;
 }
 
+int64 ComputeDirectorySize(const FilePath& root_path) {
+  int64 running_size = 0;
+  FileEnumerator file_iter(root_path, true, FileEnumerator::FILES);
+  for (FilePath current = file_iter.Next(); !current.empty();
+       current = file_iter.Next()) {
+    FileEnumerator::FindInfo info;
+    file_iter.GetFindInfo(&info);
+#if defined(OS_WIN)
+    LARGE_INTEGER li = { info.nFileSizeLow, info.nFileSizeHigh };
+    running_size += li.QuadPart;
+#else
+    running_size += info.stat.st_size;
+#endif
+  }
+  return running_size;
+}
+
 ///////////////////////////////////////////////
 // MemoryMappedFile
 
diff --git a/base/file_util.h b/base/file_util.h
index 4d6077e..fdc13ee 100644
--- a/base/file_util.h
+++ b/base/file_util.h
@@ -71,6 +71,13 @@
 int CountFilesCreatedAfter(const FilePath& path,
                            const base::Time& file_time);
 
+// Returns the total number of bytes used by all the files under |root_path|.
+// If the path does not exist the function returns 0.
+//
+// This function is implemented using the FileEnumerator class so it is not
+// particularly speedy in any platform.
+int64 ComputeDirectorySize(const FilePath& root_path);
+
 // Deletes the given path, whether it's a file or a directory.
 // If it's a directory, it's perfectly happy to delete all of the
 // directory's contents.  Passing true to recursive deletes
diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc
index fa92737..c46c39f 100644
--- a/base/file_util_unittest.cc
+++ b/base/file_util_unittest.cc
@@ -357,6 +357,34 @@
   EXPECT_EQ(0, file_util::CountFilesCreatedAfter(test_dir_, now));
 }
 
+TEST_F(FileUtilTest, FileAndDirectorySize) {
+  // Create three files of 20, 30 and 3 chars (utf8). ComputeDirectorySize
+  // should return 53 bytes.
+  FilePath file_01 = test_dir_.Append(FPL("The file 01.txt"));
+  CreateTextFile(file_01, L"12345678901234567890");
+  int64 size_f1 = 0;
+  ASSERT_TRUE(file_util::GetFileSize(file_01, &size_f1));
+  EXPECT_EQ(20ll, size_f1);
+
+  FilePath subdir_path = test_dir_.Append(FPL("Level2"));
+  file_util::CreateDirectory(subdir_path);
+
+  FilePath file_02 = subdir_path.Append(FPL("The file 02.txt"));
+  CreateTextFile(file_02, L"123456789012345678901234567890");
+  int64 size_f2 = 0;
+  ASSERT_TRUE(file_util::GetFileSize(file_02, &size_f2));
+  EXPECT_EQ(30ll, size_f2);
+
+  FilePath subsubdir_path = subdir_path.Append(FPL("Level3"));
+  file_util::CreateDirectory(subsubdir_path);
+
+  FilePath file_03 = subsubdir_path.Append(FPL("The file 03.txt"));
+  CreateTextFile(file_03, L"123");
+
+  int64 computed_size = file_util::ComputeDirectorySize(test_dir_);
+  EXPECT_EQ(size_f1 + size_f2 + 3, computed_size);
+}
+
 // Tests that the Delete function works as expected, especially
 // the recursion flag.  Also coincidentally tests PathExists.
 TEST_F(FileUtilTest, Delete) {