Base: Make file_util and file use the same code to translate from stat to File::Info

BUG=353318

Review URL: https://codereview.chromium.org/203873002

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


CrOS-Libchrome-Original-Commit: f745d724808728fe36d6475556f1a54ba15520dc
diff --git a/base/files/file.h b/base/files/file.h
index a4aea07..f1a8377 100644
--- a/base/files/file.h
+++ b/base/files/file.h
@@ -10,6 +10,10 @@
 #include <windows.h>
 #endif
 
+#if defined(OS_POSIX)
+#include <sys/stat.h>
+#endif
+
 #include "base/base_export.h"
 #include "base/basictypes.h"
 #include "base/files/scoped_file.h"
@@ -28,8 +32,13 @@
 typedef HANDLE PlatformFile;
 #elif defined(OS_POSIX)
 typedef int PlatformFile;
-#endif
 
+#if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL)
+typedef struct stat stat_wrapper_t;
+#else
+typedef struct stat64 stat_wrapper_t;
+#endif
+#endif  // defined(OS_POSIX)
 
 // Thin wrapper around an OS-level file.
 // Note that this class does not provide any support for asynchronous IO, other
@@ -120,6 +129,10 @@
   struct BASE_EXPORT Info {
     Info();
     ~Info();
+#if defined(OS_POSIX)
+    // Fills this struct with values from |stat_info|.
+    void FromStat(const stat_wrapper_t& stat_info);
+#endif
 
     // The size of the file in bytes.  Undefined when is_directory is true.
     int64 size;
diff --git a/base/files/file_posix.cc b/base/files/file_posix.cc
index 176f1f3..ad747d9 100644
--- a/base/files/file_posix.cc
+++ b/base/files/file_posix.cc
@@ -32,13 +32,11 @@
 namespace {
 
 #if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL)
-typedef struct stat stat_wrapper_t;
 static int CallFstat(int fd, stat_wrapper_t *sb) {
   base::ThreadRestrictions::AssertIOAllowed();
   return fstat(fd, sb);
 }
 #else
-typedef struct stat64 stat_wrapper_t;
 static int CallFstat(int fd, stat_wrapper_t *sb) {
   base::ThreadRestrictions::AssertIOAllowed();
   return fstat64(fd, sb);
@@ -119,6 +117,57 @@
 
 }  // namespace
 
+void File::Info::FromStat(const stat_wrapper_t& stat_info) {
+  is_directory = S_ISDIR(stat_info.st_mode);
+  is_symbolic_link = S_ISLNK(stat_info.st_mode);
+  size = stat_info.st_size;
+
+#if defined(OS_LINUX)
+  time_t last_modified_sec = stat_info.st_mtim.tv_sec;
+  int64 last_modified_nsec = stat_info.st_mtim.tv_nsec;
+  time_t last_accessed_sec = stat_info.st_atim.tv_sec;
+  int64 last_accessed_nsec = stat_info.st_atim.tv_nsec;
+  time_t creation_time_sec = stat_info.st_ctim.tv_sec;
+  int64 creation_time_nsec = stat_info.st_ctim.tv_nsec;
+#elif defined(OS_ANDROID)
+  time_t last_modified_sec = stat_info.st_mtime;
+  int64 last_modified_nsec = stat_info.st_mtime_nsec;
+  time_t last_accessed_sec = stat_info.st_atime;
+  int64 last_accessed_nsec = stat_info.st_atime_nsec;
+  time_t creation_time_sec = stat_info.st_ctime;
+  int64 creation_time_nsec = stat_info.st_ctime_nsec;
+#elif defined(OS_MACOSX) || defined(OS_IOS) || defined(OS_BSD)
+  time_t last_modified_sec = stat_info.st_mtimespec.tv_sec;
+  int64 last_modified_nsec = stat_info.st_mtimespec.tv_nsec;
+  time_t last_accessed_sec = stat_info.st_atimespec.tv_sec;
+  int64 last_accessed_nsec = stat_info.st_atimespec.tv_nsec;
+  time_t creation_time_sec = stat_info.st_ctimespec.tv_sec;
+  int64 creation_time_nsec = stat_info.st_ctimespec.tv_nsec;
+#else
+  time_t last_modified_sec = stat_info.st_mtime;
+  int64 last_modified_nsec = 0;
+  time_t last_accessed_sec = stat_info.st_atime;
+  int64 last_accessed_nsec = 0;
+  time_t creation_time_sec = stat_info.st_ctime;
+  int64 creation_time_nsec = 0;
+#endif
+
+  last_modified =
+      Time::FromTimeT(last_modified_sec) +
+      TimeDelta::FromMicroseconds(last_modified_nsec /
+                                  Time::kNanosecondsPerMicrosecond);
+
+  last_accessed =
+      Time::FromTimeT(last_accessed_sec) +
+      TimeDelta::FromMicroseconds(last_accessed_nsec /
+                                  Time::kNanosecondsPerMicrosecond);
+
+  creation_time =
+      Time::FromTimeT(creation_time_sec) +
+      TimeDelta::FromMicroseconds(creation_time_nsec /
+                                  Time::kNanosecondsPerMicrosecond);
+}
+
 // NaCl doesn't implement system calls to open files directly.
 #if !defined(OS_NACL)
 // TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here?
@@ -385,53 +434,7 @@
   if (CallFstat(file_.get(), &file_info))
     return false;
 
-  info->is_directory = S_ISDIR(file_info.st_mode);
-  info->is_symbolic_link = S_ISLNK(file_info.st_mode);
-  info->size = file_info.st_size;
-
-#if defined(OS_LINUX)
-  const time_t last_modified_sec = file_info.st_mtim.tv_sec;
-  const int64 last_modified_nsec = file_info.st_mtim.tv_nsec;
-  const time_t last_accessed_sec = file_info.st_atim.tv_sec;
-  const int64 last_accessed_nsec = file_info.st_atim.tv_nsec;
-  const time_t creation_time_sec = file_info.st_ctim.tv_sec;
-  const int64 creation_time_nsec = file_info.st_ctim.tv_nsec;
-#elif defined(OS_ANDROID)
-  const time_t last_modified_sec = file_info.st_mtime;
-  const int64 last_modified_nsec = file_info.st_mtime_nsec;
-  const time_t last_accessed_sec = file_info.st_atime;
-  const int64 last_accessed_nsec = file_info.st_atime_nsec;
-  const time_t creation_time_sec = file_info.st_ctime;
-  const int64 creation_time_nsec = file_info.st_ctime_nsec;
-#elif defined(OS_MACOSX) || defined(OS_IOS) || defined(OS_BSD)
-  const time_t last_modified_sec = file_info.st_mtimespec.tv_sec;
-  const int64 last_modified_nsec = file_info.st_mtimespec.tv_nsec;
-  const time_t last_accessed_sec = file_info.st_atimespec.tv_sec;
-  const int64 last_accessed_nsec = file_info.st_atimespec.tv_nsec;
-  const time_t creation_time_sec = file_info.st_ctimespec.tv_sec;
-  const int64 creation_time_nsec = file_info.st_ctimespec.tv_nsec;
-#else
-  // TODO(gavinp): Investigate a good high resolution option for OS_NACL.
-  const time_t last_modified_sec = file_info.st_mtime;
-  const int64 last_modified_nsec = 0;
-  const time_t last_accessed_sec = file_info.st_atime;
-  const int64 last_accessed_nsec = 0;
-  const time_t creation_time_sec = file_info.st_ctime;
-  const int64 creation_time_nsec = 0;
-#endif
-
-  info->last_modified =
-      base::Time::FromTimeT(last_modified_sec) +
-      base::TimeDelta::FromMicroseconds(last_modified_nsec /
-                                        base::Time::kNanosecondsPerMicrosecond);
-  info->last_accessed =
-      base::Time::FromTimeT(last_accessed_sec) +
-      base::TimeDelta::FromMicroseconds(last_accessed_nsec /
-                                        base::Time::kNanosecondsPerMicrosecond);
-  info->creation_time =
-      base::Time::FromTimeT(creation_time_sec) +
-      base::TimeDelta::FromMicroseconds(creation_time_nsec /
-                                        base::Time::kNanosecondsPerMicrosecond);
+  info->FromStat(file_info);
   return true;
 }
 
diff --git a/base/files/file_proxy_unittest.cc b/base/files/file_proxy_unittest.cc
index b5e1002..bb7e6c3 100644
--- a/base/files/file_proxy_unittest.cc
+++ b/base/files/file_proxy_unittest.cc
@@ -209,9 +209,6 @@
   EXPECT_EQ(expected_info.size, file_info_.size);
   EXPECT_EQ(expected_info.is_directory, file_info_.is_directory);
   EXPECT_EQ(expected_info.is_symbolic_link, file_info_.is_symbolic_link);
-
-  File file = proxy.TakeFile();
-  EXPECT_TRUE(file.GetInfo(&expected_info));
   EXPECT_EQ(expected_info.last_modified, file_info_.last_modified);
   EXPECT_EQ(expected_info.creation_time, file_info_.creation_time);
 }