1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/files/file.h"
6 #include "base/files/file_path.h"
7 #include "base/files/file_tracing.h"
8 #include "base/metrics/histogram.h"
9 #include "base/timer/elapsed_timer.h"
10 #include "build/build_config.h"
11 
12 namespace base {
13 
Info()14 File::Info::Info()
15     : size(0),
16       is_directory(false),
17       is_symbolic_link(false) {
18 }
19 
~Info()20 File::Info::~Info() {
21 }
22 
File()23 File::File()
24     : error_details_(FILE_ERROR_FAILED),
25       created_(false),
26       async_(false) {
27 }
28 
29 #if !defined(OS_NACL)
File(const FilePath & path,uint32_t flags)30 File::File(const FilePath& path, uint32_t flags)
31     : error_details_(FILE_OK), created_(false), async_(false) {
32   Initialize(path, flags);
33 }
34 #endif
35 
File(PlatformFile platform_file)36 File::File(PlatformFile platform_file)
37     : file_(platform_file),
38       error_details_(FILE_OK),
39       created_(false),
40       async_(false) {
41 #if defined(OS_POSIX)
42   DCHECK_GE(platform_file, -1);
43 #endif
44 }
45 
File(Error error_details)46 File::File(Error error_details)
47     : error_details_(error_details),
48       created_(false),
49       async_(false) {
50 }
51 
File(File && other)52 File::File(File&& other)
53     : file_(other.TakePlatformFile()),
54       tracing_path_(other.tracing_path_),
55       error_details_(other.error_details()),
56       created_(other.created()),
57       async_(other.async_) {}
58 
~File()59 File::~File() {
60   // Go through the AssertIOAllowed logic.
61   Close();
62 }
63 
64 // static
CreateForAsyncHandle(PlatformFile platform_file)65 File File::CreateForAsyncHandle(PlatformFile platform_file) {
66   File file(platform_file);
67   // It would be nice if we could validate that |platform_file| was opened with
68   // FILE_FLAG_OVERLAPPED on Windows but this doesn't appear to be possible.
69   file.async_ = true;
70   return file;
71 }
72 
operator =(File && other)73 File& File::operator=(File&& other) {
74   DCHECK_NE(this, &other);
75   Close();
76   SetPlatformFile(other.TakePlatformFile());
77   tracing_path_ = other.tracing_path_;
78   error_details_ = other.error_details();
79   created_ = other.created();
80   async_ = other.async_;
81   return *this;
82 }
83 
84 #if !defined(OS_NACL)
Initialize(const FilePath & path,uint32_t flags)85 void File::Initialize(const FilePath& path, uint32_t flags) {
86   if (path.ReferencesParent()) {
87     error_details_ = FILE_ERROR_ACCESS_DENIED;
88     return;
89   }
90   if (FileTracing::IsCategoryEnabled())
91     tracing_path_ = path;
92   SCOPED_FILE_TRACE("Initialize");
93   DoInitialize(path, flags);
94 }
95 #endif
96 
ErrorToString(Error error)97 std::string File::ErrorToString(Error error) {
98   switch (error) {
99     case FILE_OK:
100       return "FILE_OK";
101     case FILE_ERROR_FAILED:
102       return "FILE_ERROR_FAILED";
103     case FILE_ERROR_IN_USE:
104       return "FILE_ERROR_IN_USE";
105     case FILE_ERROR_EXISTS:
106       return "FILE_ERROR_EXISTS";
107     case FILE_ERROR_NOT_FOUND:
108       return "FILE_ERROR_NOT_FOUND";
109     case FILE_ERROR_ACCESS_DENIED:
110       return "FILE_ERROR_ACCESS_DENIED";
111     case FILE_ERROR_TOO_MANY_OPENED:
112       return "FILE_ERROR_TOO_MANY_OPENED";
113     case FILE_ERROR_NO_MEMORY:
114       return "FILE_ERROR_NO_MEMORY";
115     case FILE_ERROR_NO_SPACE:
116       return "FILE_ERROR_NO_SPACE";
117     case FILE_ERROR_NOT_A_DIRECTORY:
118       return "FILE_ERROR_NOT_A_DIRECTORY";
119     case FILE_ERROR_INVALID_OPERATION:
120       return "FILE_ERROR_INVALID_OPERATION";
121     case FILE_ERROR_SECURITY:
122       return "FILE_ERROR_SECURITY";
123     case FILE_ERROR_ABORT:
124       return "FILE_ERROR_ABORT";
125     case FILE_ERROR_NOT_A_FILE:
126       return "FILE_ERROR_NOT_A_FILE";
127     case FILE_ERROR_NOT_EMPTY:
128       return "FILE_ERROR_NOT_EMPTY";
129     case FILE_ERROR_INVALID_URL:
130       return "FILE_ERROR_INVALID_URL";
131     case FILE_ERROR_IO:
132       return "FILE_ERROR_IO";
133     case FILE_ERROR_MAX:
134       break;
135   }
136 
137   NOTREACHED();
138   return "";
139 }
140 
Flush()141 bool File::Flush() {
142   ElapsedTimer timer;
143   SCOPED_FILE_TRACE("Flush");
144   bool return_value = DoFlush();
145   UMA_HISTOGRAM_TIMES("PlatformFile.FlushTime", timer.Elapsed());
146   return return_value;
147 }
148 
149 }  // namespace base
150