OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/base/file_stream_context.h" | 5 #include "net/base/file_stream_context.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 | 8 |
9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 offset.HighPart = overlapped->OffsetHigh; | 33 offset.HighPart = overlapped->OffsetHigh; |
34 offset.QuadPart += static_cast<LONGLONG>(count); | 34 offset.QuadPart += static_cast<LONGLONG>(count); |
35 SetOffset(overlapped, offset); | 35 SetOffset(overlapped, offset); |
36 } | 36 } |
37 | 37 |
38 } // namespace | 38 } // namespace |
39 | 39 |
40 FileStream::Context::Context(const BoundNetLog& bound_net_log, | 40 FileStream::Context::Context(const BoundNetLog& bound_net_log, |
41 const scoped_refptr<base::TaskRunner>& task_runner) | 41 const scoped_refptr<base::TaskRunner>& task_runner) |
42 : io_context_(), | 42 : io_context_(), |
43 file_(base::kInvalidPlatformFileValue), | |
44 record_uma_(false), | 43 record_uma_(false), |
45 async_in_progress_(false), | 44 async_in_progress_(false), |
46 orphaned_(false), | 45 orphaned_(false), |
| 46 async_(false), |
47 bound_net_log_(bound_net_log), | 47 bound_net_log_(bound_net_log), |
48 error_source_(FILE_ERROR_SOURCE_COUNT), | 48 error_source_(FILE_ERROR_SOURCE_COUNT), |
49 task_runner_(task_runner) { | 49 task_runner_(task_runner) { |
50 io_context_.handler = this; | 50 io_context_.handler = this; |
51 memset(&io_context_.overlapped, 0, sizeof(io_context_.overlapped)); | 51 memset(&io_context_.overlapped, 0, sizeof(io_context_.overlapped)); |
52 } | 52 } |
53 | 53 |
54 FileStream::Context::Context(base::PlatformFile file, | 54 FileStream::Context::Context(base::File file, |
55 const BoundNetLog& bound_net_log, | 55 const BoundNetLog& bound_net_log, |
56 int open_flags, | |
57 const scoped_refptr<base::TaskRunner>& task_runner) | 56 const scoped_refptr<base::TaskRunner>& task_runner) |
58 : io_context_(), | 57 : io_context_(), |
59 file_(file), | 58 file_(file.Pass()), |
60 record_uma_(false), | 59 record_uma_(false), |
61 async_in_progress_(false), | 60 async_in_progress_(false), |
62 orphaned_(false), | 61 orphaned_(false), |
| 62 async_(false), |
63 bound_net_log_(bound_net_log), | 63 bound_net_log_(bound_net_log), |
64 error_source_(FILE_ERROR_SOURCE_COUNT), | 64 error_source_(FILE_ERROR_SOURCE_COUNT), |
65 task_runner_(task_runner) { | 65 task_runner_(task_runner) { |
66 io_context_.handler = this; | 66 io_context_.handler = this; |
67 memset(&io_context_.overlapped, 0, sizeof(io_context_.overlapped)); | 67 memset(&io_context_.overlapped, 0, sizeof(io_context_.overlapped)); |
68 if (file_ != base::kInvalidPlatformFileValue && | 68 if (file_.IsValid() && file_.async()) |
69 (open_flags & base::PLATFORM_FILE_ASYNC)) { | |
70 OnAsyncFileOpened(); | 69 OnAsyncFileOpened(); |
71 } | 70 } |
| 71 |
| 72 FileStream::Context::Context(base::File file, |
| 73 int flags, |
| 74 const BoundNetLog& bound_net_log, |
| 75 const scoped_refptr<base::TaskRunner>& task_runner) |
| 76 : io_context_(), |
| 77 file_(file.Pass()), |
| 78 record_uma_(false), |
| 79 async_in_progress_(false), |
| 80 orphaned_(false), |
| 81 async_((flags & base::File::FLAG_ASYNC) == base::File::FLAG_ASYNC), |
| 82 bound_net_log_(bound_net_log), |
| 83 error_source_(FILE_ERROR_SOURCE_COUNT), |
| 84 task_runner_(task_runner) { |
| 85 io_context_.handler = this; |
| 86 memset(&io_context_.overlapped, 0, sizeof(io_context_.overlapped)); |
| 87 if (file_.IsValid() && (file_.async() || flags & base::File::FLAG_ASYNC)) |
| 88 OnAsyncFileOpened(); |
72 } | 89 } |
73 | 90 |
74 FileStream::Context::~Context() { | 91 FileStream::Context::~Context() { |
75 } | 92 } |
76 | 93 |
77 int64 FileStream::Context::GetFileSize() const { | 94 int64 FileStream::Context::GetFileSize() const { |
78 LARGE_INTEGER file_size; | 95 LARGE_INTEGER file_size; |
79 if (!GetFileSizeEx(file_, &file_size)) { | 96 if (!GetFileSizeEx(file_.GetPlatformFile(), &file_size)) { |
80 IOResult error = IOResult::FromOSError(GetLastError()); | 97 IOResult error = IOResult::FromOSError(GetLastError()); |
81 LOG(WARNING) << "GetFileSizeEx failed: " << error.os_error; | 98 LOG(WARNING) << "GetFileSizeEx failed: " << error.os_error; |
82 RecordError(error, FILE_ERROR_SOURCE_GET_SIZE); | 99 RecordError(error, FILE_ERROR_SOURCE_GET_SIZE); |
83 return error.result; | 100 return error.result; |
84 } | 101 } |
85 | 102 |
86 return file_size.QuadPart; | 103 return file_size.QuadPart; |
87 } | 104 } |
88 | 105 |
89 int FileStream::Context::ReadAsync(IOBuffer* buf, | 106 int FileStream::Context::ReadAsync(IOBuffer* buf, |
90 int buf_len, | 107 int buf_len, |
91 const CompletionCallback& callback) { | 108 const CompletionCallback& callback) { |
92 DCHECK(!async_in_progress_); | 109 DCHECK(!async_in_progress_); |
93 error_source_ = FILE_ERROR_SOURCE_READ; | 110 error_source_ = FILE_ERROR_SOURCE_READ; |
94 | 111 |
95 DWORD bytes_read; | 112 DWORD bytes_read; |
96 if (!ReadFile(file_, buf->data(), buf_len, | 113 if (!ReadFile(file_.GetPlatformFile(), buf->data(), buf_len, |
97 &bytes_read, &io_context_.overlapped)) { | 114 &bytes_read, &io_context_.overlapped)) { |
98 IOResult error = IOResult::FromOSError(GetLastError()); | 115 IOResult error = IOResult::FromOSError(GetLastError()); |
99 if (error.os_error == ERROR_IO_PENDING) { | 116 if (error.os_error == ERROR_IO_PENDING) { |
100 IOCompletionIsPending(callback, buf); | 117 IOCompletionIsPending(callback, buf); |
101 } else if (error.os_error == ERROR_HANDLE_EOF) { | 118 } else if (error.os_error == ERROR_HANDLE_EOF) { |
102 return 0; // Report EOF by returning 0 bytes read. | 119 return 0; // Report EOF by returning 0 bytes read. |
103 } else { | 120 } else { |
104 LOG(WARNING) << "ReadFile failed: " << error.os_error; | 121 LOG(WARNING) << "ReadFile failed: " << error.os_error; |
105 RecordError(error, FILE_ERROR_SOURCE_READ); | 122 RecordError(error, FILE_ERROR_SOURCE_READ); |
106 } | 123 } |
107 return error.result; | 124 return error.result; |
108 } | 125 } |
109 | 126 |
110 IOCompletionIsPending(callback, buf); | 127 IOCompletionIsPending(callback, buf); |
111 return ERR_IO_PENDING; | 128 return ERR_IO_PENDING; |
112 } | 129 } |
113 | 130 |
114 int FileStream::Context::ReadSync(char* buf, int buf_len) { | 131 int FileStream::Context::ReadSync(char* buf, int buf_len) { |
115 DWORD bytes_read; | 132 DWORD bytes_read; |
116 if (!ReadFile(file_, buf, buf_len, &bytes_read, NULL)) { | 133 if (!ReadFile(file_.GetPlatformFile(), buf, buf_len, &bytes_read, NULL)) { |
117 IOResult error = IOResult::FromOSError(GetLastError()); | 134 IOResult error = IOResult::FromOSError(GetLastError()); |
118 if (error.os_error == ERROR_HANDLE_EOF) { | 135 if (error.os_error == ERROR_HANDLE_EOF) { |
119 return 0; // Report EOF by returning 0 bytes read. | 136 return 0; // Report EOF by returning 0 bytes read. |
120 } else { | 137 } else { |
121 LOG(WARNING) << "ReadFile failed: " << error.os_error; | 138 LOG(WARNING) << "ReadFile failed: " << error.os_error; |
122 RecordError(error, FILE_ERROR_SOURCE_READ); | 139 RecordError(error, FILE_ERROR_SOURCE_READ); |
123 } | 140 } |
124 return error.result; | 141 return error.result; |
125 } | 142 } |
126 | 143 |
127 return bytes_read; | 144 return bytes_read; |
128 } | 145 } |
129 | 146 |
130 int FileStream::Context::WriteAsync(IOBuffer* buf, | 147 int FileStream::Context::WriteAsync(IOBuffer* buf, |
131 int buf_len, | 148 int buf_len, |
132 const CompletionCallback& callback) { | 149 const CompletionCallback& callback) { |
133 error_source_ = FILE_ERROR_SOURCE_WRITE; | 150 error_source_ = FILE_ERROR_SOURCE_WRITE; |
134 | 151 |
135 DWORD bytes_written = 0; | 152 DWORD bytes_written = 0; |
136 if (!WriteFile(file_, buf->data(), buf_len, | 153 if (!WriteFile(file_.GetPlatformFile(), buf->data(), buf_len, |
137 &bytes_written, &io_context_.overlapped)) { | 154 &bytes_written, &io_context_.overlapped)) { |
138 IOResult error = IOResult::FromOSError(GetLastError()); | 155 IOResult error = IOResult::FromOSError(GetLastError()); |
139 if (error.os_error == ERROR_IO_PENDING) { | 156 if (error.os_error == ERROR_IO_PENDING) { |
140 IOCompletionIsPending(callback, buf); | 157 IOCompletionIsPending(callback, buf); |
141 } else { | 158 } else { |
142 LOG(WARNING) << "WriteFile failed: " << error.os_error; | 159 LOG(WARNING) << "WriteFile failed: " << error.os_error; |
143 RecordError(error, FILE_ERROR_SOURCE_WRITE); | 160 RecordError(error, FILE_ERROR_SOURCE_WRITE); |
144 } | 161 } |
145 return error.result; | 162 return error.result; |
146 } | 163 } |
147 | 164 |
148 IOCompletionIsPending(callback, buf); | 165 IOCompletionIsPending(callback, buf); |
149 return ERR_IO_PENDING; | 166 return ERR_IO_PENDING; |
150 } | 167 } |
151 | 168 |
152 int FileStream::Context::WriteSync(const char* buf, int buf_len) { | 169 int FileStream::Context::WriteSync(const char* buf, int buf_len) { |
153 DWORD bytes_written = 0; | 170 DWORD bytes_written = 0; |
154 if (!WriteFile(file_, buf, buf_len, &bytes_written, NULL)) { | 171 if (!WriteFile(file_.GetPlatformFile(), buf, buf_len, &bytes_written, NULL)) { |
155 IOResult error = IOResult::FromOSError(GetLastError()); | 172 IOResult error = IOResult::FromOSError(GetLastError()); |
156 LOG(WARNING) << "WriteFile failed: " << error.os_error; | 173 LOG(WARNING) << "WriteFile failed: " << error.os_error; |
157 RecordError(error, FILE_ERROR_SOURCE_WRITE); | 174 RecordError(error, FILE_ERROR_SOURCE_WRITE); |
158 return error.result; | 175 return error.result; |
159 } | 176 } |
160 | 177 |
161 return bytes_written; | 178 return bytes_written; |
162 } | 179 } |
163 | 180 |
164 int FileStream::Context::Truncate(int64 bytes) { | 181 int FileStream::Context::Truncate(int64 bytes) { |
165 if (!SetEndOfFile(file_)) { | 182 if (!SetEndOfFile(file_.GetPlatformFile())) { |
166 IOResult error = IOResult::FromOSError(GetLastError()); | 183 IOResult error = IOResult::FromOSError(GetLastError()); |
167 LOG(WARNING) << "SetEndOfFile failed: " << error.os_error; | 184 LOG(WARNING) << "SetEndOfFile failed: " << error.os_error; |
168 RecordError(error, FILE_ERROR_SOURCE_SET_EOF); | 185 RecordError(error, FILE_ERROR_SOURCE_SET_EOF); |
169 return error.result; | 186 return error.result; |
170 } | 187 } |
171 | 188 |
172 return bytes; | 189 return bytes; |
173 } | 190 } |
174 | 191 |
175 void FileStream::Context::OnAsyncFileOpened() { | 192 void FileStream::Context::OnAsyncFileOpened() { |
176 base::MessageLoopForIO::current()->RegisterIOHandler(file_, this); | 193 base::MessageLoopForIO::current()->RegisterIOHandler(file_.GetPlatformFile(), |
| 194 this); |
177 } | 195 } |
178 | 196 |
179 FileStream::Context::IOResult FileStream::Context::SeekFileImpl(Whence whence, | 197 FileStream::Context::IOResult FileStream::Context::SeekFileImpl(Whence whence, |
180 int64 offset) { | 198 int64 offset) { |
181 LARGE_INTEGER distance, res; | 199 LARGE_INTEGER distance, res; |
182 distance.QuadPart = offset; | 200 distance.QuadPart = offset; |
183 DWORD move_method = static_cast<DWORD>(whence); | 201 DWORD move_method = static_cast<DWORD>(whence); |
184 if (SetFilePointerEx(file_, distance, &res, move_method)) { | 202 if (SetFilePointerEx(file_.GetPlatformFile(), distance, &res, move_method)) { |
185 SetOffset(&io_context_.overlapped, res); | 203 SetOffset(&io_context_.overlapped, res); |
186 return IOResult(res.QuadPart, 0); | 204 return IOResult(res.QuadPart, 0); |
187 } | 205 } |
188 | 206 |
189 return IOResult::FromOSError(GetLastError()); | 207 return IOResult::FromOSError(GetLastError()); |
190 } | 208 } |
191 | 209 |
192 FileStream::Context::IOResult FileStream::Context::FlushFileImpl() { | 210 FileStream::Context::IOResult FileStream::Context::FlushFileImpl() { |
193 if (FlushFileBuffers(file_)) | 211 if (FlushFileBuffers(file_.GetPlatformFile())) |
194 return IOResult(OK, 0); | 212 return IOResult(OK, 0); |
195 | 213 |
196 return IOResult::FromOSError(GetLastError()); | 214 return IOResult::FromOSError(GetLastError()); |
197 } | |
198 | |
199 FileStream::Context::IOResult FileStream::Context::CloseFileImpl() { | |
200 bool success = base::ClosePlatformFile(file_); | |
201 file_ = base::kInvalidPlatformFileValue; | |
202 if (success) | |
203 return IOResult(OK, 0); | |
204 | |
205 return IOResult::FromOSError(GetLastError()); | |
206 } | 215 } |
207 | 216 |
208 void FileStream::Context::IOCompletionIsPending( | 217 void FileStream::Context::IOCompletionIsPending( |
209 const CompletionCallback& callback, | 218 const CompletionCallback& callback, |
210 IOBuffer* buf) { | 219 IOBuffer* buf) { |
211 DCHECK(callback_.is_null()); | 220 DCHECK(callback_.is_null()); |
212 callback_ = callback; | 221 callback_ = callback; |
213 in_flight_buf_ = buf; // Hold until the async operation ends. | 222 in_flight_buf_ = buf; // Hold until the async operation ends. |
214 async_in_progress_ = true; | 223 async_in_progress_ = true; |
215 } | 224 } |
(...skipping 27 matching lines...) Expand all Loading... |
243 } | 252 } |
244 | 253 |
245 CompletionCallback temp_callback = callback_; | 254 CompletionCallback temp_callback = callback_; |
246 callback_.Reset(); | 255 callback_.Reset(); |
247 scoped_refptr<IOBuffer> temp_buf = in_flight_buf_; | 256 scoped_refptr<IOBuffer> temp_buf = in_flight_buf_; |
248 in_flight_buf_ = NULL; | 257 in_flight_buf_ = NULL; |
249 temp_callback.Run(result); | 258 temp_callback.Run(result); |
250 } | 259 } |
251 | 260 |
252 } // namespace net | 261 } // namespace net |
OLD | NEW |