| 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 |