Chromium Code Reviews| 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/file_path.h" | 9 #include "base/file_path.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 65 OnAsyncFileOpened(); | 65 OnAsyncFileOpened(); |
| 66 } | 66 } |
| 67 } | 67 } |
| 68 | 68 |
| 69 FileStream::Context::~Context() { | 69 FileStream::Context::~Context() { |
| 70 } | 70 } |
| 71 | 71 |
| 72 int64 FileStream::Context::GetFileSize() const { | 72 int64 FileStream::Context::GetFileSize() const { |
| 73 LARGE_INTEGER file_size; | 73 LARGE_INTEGER file_size; |
| 74 if (!GetFileSizeEx(file_, &file_size)) { | 74 if (!GetFileSizeEx(file_, &file_size)) { |
| 75 DWORD error = GetLastError(); | 75 IOResult error = IOResult::FromOSError(GetLastError()); |
| 76 LOG(WARNING) << "GetFileSizeEx failed: " << error; | 76 LOG(WARNING) << "GetFileSizeEx failed: " << error.os_error; |
| 77 return RecordAndMapError(error, FILE_ERROR_SOURCE_GET_SIZE); | 77 RecordError(error, FILE_ERROR_SOURCE_GET_SIZE); |
| 78 return error.result; | |
| 78 } | 79 } |
| 79 | 80 |
| 80 return file_size.QuadPart; | 81 return file_size.QuadPart; |
| 81 } | 82 } |
| 82 | 83 |
| 83 int FileStream::Context::ReadAsync(IOBuffer* buf, | 84 int FileStream::Context::ReadAsync(IOBuffer* buf, |
| 84 int buf_len, | 85 int buf_len, |
| 85 const CompletionCallback& callback) { | 86 const CompletionCallback& callback) { |
| 86 DCHECK(!async_in_progress_); | 87 DCHECK(!async_in_progress_); |
| 87 error_source_ = FILE_ERROR_SOURCE_READ; | 88 error_source_ = FILE_ERROR_SOURCE_READ; |
| 88 | 89 |
| 89 int rv = 0; | |
| 90 | |
| 91 DWORD bytes_read; | 90 DWORD bytes_read; |
| 92 if (!ReadFile(file_, buf->data(), buf_len, | 91 if (!ReadFile(file_, buf->data(), buf_len, |
| 93 &bytes_read, &io_context_.overlapped)) { | 92 &bytes_read, &io_context_.overlapped)) { |
| 94 DWORD error = GetLastError(); | 93 IOResult error = IOResult::FromOSError(GetLastError()); |
| 95 if (error == ERROR_IO_PENDING) { | 94 if (error.os_error == ERROR_IO_PENDING) { |
| 96 IOCompletionIsPending(callback, buf); | 95 IOCompletionIsPending(callback, buf); |
| 97 rv = ERR_IO_PENDING; | 96 } else if (error.os_error == ERROR_HANDLE_EOF) { |
| 98 } else if (error == ERROR_HANDLE_EOF) { | 97 return 0; // Report EOF by returning 0 bytes read. |
| 99 rv = 0; // Report EOF by returning 0 bytes read. | |
| 100 } else { | 98 } else { |
| 101 LOG(WARNING) << "ReadFile failed: " << error; | 99 LOG(WARNING) << "ReadFile failed: " << error.os_error; |
| 102 rv = RecordAndMapError(error, FILE_ERROR_SOURCE_READ); | 100 RecordError(error, FILE_ERROR_SOURCE_READ); |
| 103 } | 101 } |
| 104 } else { | 102 return error.result; |
| 105 IOCompletionIsPending(callback, buf); | |
| 106 rv = ERR_IO_PENDING; | |
| 107 } | 103 } |
| 108 return rv; | 104 |
| 105 return bytes_read; | |
|
mmenke
2013/02/22 16:24:59
Skimming over the MSDN docs, the old behavior look
Sergey Ulanov
2013/02/22 21:04:06
This method would have to be updated either way (f
mmenke
2013/02/22 21:13:17
It's not about the size, it's about the unrelated
Sergey Ulanov
2013/02/22 21:51:47
Yeah, I understand and agree that in general it wo
| |
| 109 } | 106 } |
| 110 | 107 |
| 111 int FileStream::Context::ReadSync(char* buf, int buf_len) { | 108 int FileStream::Context::ReadSync(char* buf, int buf_len) { |
| 112 int rv = 0; | |
| 113 | |
| 114 DWORD bytes_read; | 109 DWORD bytes_read; |
| 115 if (!ReadFile(file_, buf, buf_len, &bytes_read, NULL)) { | 110 if (!ReadFile(file_, buf, buf_len, &bytes_read, NULL)) { |
| 116 DWORD error = GetLastError(); | 111 IOResult error = IOResult::FromOSError(GetLastError()); |
| 117 if (error == ERROR_HANDLE_EOF) { | 112 if (error.os_error == ERROR_HANDLE_EOF) { |
| 118 rv = 0; // Report EOF by returning 0 bytes read. | 113 return 0; // Report EOF by returning 0 bytes read. |
| 119 } else { | 114 } else { |
| 120 LOG(WARNING) << "ReadFile failed: " << error; | 115 LOG(WARNING) << "ReadFile failed: " << error.os_error; |
| 121 rv = RecordAndMapError(error, FILE_ERROR_SOURCE_READ); | 116 RecordError(error, FILE_ERROR_SOURCE_READ); |
| 122 } | 117 } |
| 123 } else { | 118 return error.result; |
| 124 rv = static_cast<int>(bytes_read); | |
| 125 } | 119 } |
| 126 return rv; | 120 |
| 121 return bytes_read; | |
| 127 } | 122 } |
| 128 | 123 |
| 129 int FileStream::Context::WriteAsync(IOBuffer* buf, | 124 int FileStream::Context::WriteAsync(IOBuffer* buf, |
| 130 int buf_len, | 125 int buf_len, |
| 131 const CompletionCallback& callback) { | 126 const CompletionCallback& callback) { |
| 132 error_source_ = FILE_ERROR_SOURCE_WRITE; | 127 error_source_ = FILE_ERROR_SOURCE_WRITE; |
| 133 | 128 |
| 134 int rv = 0; | |
| 135 DWORD bytes_written = 0; | 129 DWORD bytes_written = 0; |
| 136 if (!WriteFile(file_, buf->data(), buf_len, | 130 if (!WriteFile(file_, buf->data(), buf_len, |
| 137 &bytes_written, &io_context_.overlapped)) { | 131 &bytes_written, &io_context_.overlapped)) { |
| 138 DWORD error = GetLastError(); | 132 IOResult error = IOResult::FromOSError(GetLastError()); |
| 139 if (error == ERROR_IO_PENDING) { | 133 if (error.os_error == ERROR_IO_PENDING) { |
| 140 IOCompletionIsPending(callback, buf); | 134 IOCompletionIsPending(callback, buf); |
| 141 rv = ERR_IO_PENDING; | |
| 142 } else { | 135 } else { |
| 143 LOG(WARNING) << "WriteFile failed: " << error; | 136 LOG(WARNING) << "WriteFile failed: " << error.os_error; |
| 144 rv = RecordAndMapError(error, FILE_ERROR_SOURCE_WRITE); | 137 RecordError(error, FILE_ERROR_SOURCE_WRITE); |
| 145 } | 138 } |
| 146 } else { | 139 return error.result; |
| 147 IOCompletionIsPending(callback, buf); | |
| 148 rv = ERR_IO_PENDING; | |
| 149 } | 140 } |
| 150 return rv; | 141 |
| 142 return bytes_written; | |
|
mmenke
2013/02/22 16:24:59
See above comment.
Sergey Ulanov
2013/02/22 21:04:06
Same here.
| |
| 151 } | 143 } |
| 152 | 144 |
| 153 int FileStream::Context::WriteSync(const char* buf, int buf_len) { | 145 int FileStream::Context::WriteSync(const char* buf, int buf_len) { |
| 154 int rv = 0; | |
| 155 DWORD bytes_written = 0; | 146 DWORD bytes_written = 0; |
| 156 if (!WriteFile(file_, buf, buf_len, &bytes_written, NULL)) { | 147 if (!WriteFile(file_, buf, buf_len, &bytes_written, NULL)) { |
| 157 DWORD error = GetLastError(); | 148 IOResult error = IOResult::FromOSError(GetLastError()); |
| 158 LOG(WARNING) << "WriteFile failed: " << error; | 149 LOG(WARNING) << "WriteFile failed: " << error.os_error; |
| 159 rv = RecordAndMapError(error, FILE_ERROR_SOURCE_WRITE); | 150 RecordError(error, FILE_ERROR_SOURCE_WRITE); |
| 160 } else { | 151 return error.result; |
| 161 rv = static_cast<int>(bytes_written); | |
| 162 } | 152 } |
| 163 return rv; | 153 |
| 154 return bytes_written; | |
| 164 } | 155 } |
| 165 | 156 |
| 166 int FileStream::Context::Truncate(int64 bytes) { | 157 int FileStream::Context::Truncate(int64 bytes) { |
| 167 BOOL result = SetEndOfFile(file_); | 158 if (!SetEndOfFile(file_)) { |
| 168 if (result) | 159 IOResult error = IOResult::FromOSError(GetLastError()); |
| 169 return bytes; | 160 LOG(WARNING) << "SetEndOfFile failed: " << error.os_error; |
| 161 RecordError(error, FILE_ERROR_SOURCE_SET_EOF); | |
| 162 return error.result; | |
| 163 } | |
| 170 | 164 |
| 171 DWORD error = GetLastError(); | 165 return bytes; |
| 172 LOG(WARNING) << "SetEndOfFile failed: " << error; | |
| 173 return RecordAndMapError(error, FILE_ERROR_SOURCE_SET_EOF); | |
| 174 } | 166 } |
| 175 | 167 |
| 176 void FileStream::Context::OnAsyncFileOpened() { | 168 void FileStream::Context::OnAsyncFileOpened() { |
| 177 MessageLoopForIO::current()->RegisterIOHandler(file_, this); | 169 MessageLoopForIO::current()->RegisterIOHandler(file_, this); |
| 178 } | 170 } |
| 179 | 171 |
| 180 int64 FileStream::Context::SeekFileImpl(Whence whence, int64 offset) { | 172 FileStream::Context::IOResult FileStream::Context::SeekFileImpl(Whence whence, |
| 173 int64 offset) { | |
| 181 LARGE_INTEGER distance, res; | 174 LARGE_INTEGER distance, res; |
| 182 distance.QuadPart = offset; | 175 distance.QuadPart = offset; |
| 183 DWORD move_method = static_cast<DWORD>(whence); | 176 DWORD move_method = static_cast<DWORD>(whence); |
| 184 if (SetFilePointerEx(file_, distance, &res, move_method)) { | 177 if (SetFilePointerEx(file_, distance, &res, move_method)) { |
| 185 SetOffset(&io_context_.overlapped, res); | 178 SetOffset(&io_context_.overlapped, res); |
| 186 return res.QuadPart; | 179 return IOResult(res.QuadPart, 0); |
| 187 } | 180 } |
| 188 | 181 |
| 189 return -static_cast<int>(GetLastError()); | 182 return IOResult::FromOSError(GetLastError()); |
| 190 } | 183 } |
| 191 | 184 |
| 192 int64 FileStream::Context::FlushFileImpl() { | 185 FileStream::Context::IOResult FileStream::Context::FlushFileImpl() { |
| 193 if (FlushFileBuffers(file_)) | 186 if (FlushFileBuffers(file_)) |
| 194 return OK; | 187 return IOResult(OK, 0); |
| 195 | 188 |
| 196 return -static_cast<int>(GetLastError()); | 189 return IOResult::FromOSError(GetLastError()); |
| 197 } | 190 } |
| 198 | 191 |
| 199 void FileStream::Context::IOCompletionIsPending( | 192 void FileStream::Context::IOCompletionIsPending( |
| 200 const CompletionCallback& callback, | 193 const CompletionCallback& callback, |
| 201 IOBuffer* buf) { | 194 IOBuffer* buf) { |
| 202 DCHECK(callback_.is_null()); | 195 DCHECK(callback_.is_null()); |
| 203 callback_ = callback; | 196 callback_ = callback; |
| 204 in_flight_buf_ = buf; // Hold until the async operation ends. | 197 in_flight_buf_ = buf; // Hold until the async operation ends. |
| 205 async_in_progress_ = true; | 198 async_in_progress_ = true; |
| 206 } | 199 } |
| 207 | 200 |
| 208 void FileStream::Context::OnIOCompleted(MessageLoopForIO::IOContext* context, | 201 void FileStream::Context::OnIOCompleted(MessageLoopForIO::IOContext* context, |
| 209 DWORD bytes_read, | 202 DWORD bytes_read, |
| 210 DWORD error) { | 203 DWORD error) { |
| 211 DCHECK_EQ(&io_context_, context); | 204 DCHECK_EQ(&io_context_, context); |
| 212 DCHECK(!callback_.is_null()); | 205 DCHECK(!callback_.is_null()); |
| 213 DCHECK(async_in_progress_); | 206 DCHECK(async_in_progress_); |
| 214 | 207 |
| 215 async_in_progress_ = false; | 208 async_in_progress_ = false; |
| 216 if (orphaned_) { | 209 if (orphaned_) { |
| 217 callback_.Reset(); | 210 callback_.Reset(); |
| 218 in_flight_buf_ = NULL; | 211 in_flight_buf_ = NULL; |
| 219 CloseAndDelete(); | 212 CloseAndDelete(); |
| 220 return; | 213 return; |
| 221 } | 214 } |
| 222 | 215 |
| 223 int result = static_cast<int>(bytes_read); | 216 IOResult result; |
|
mmenke
2013/02/22 16:24:59
Don't think we need this here. Can be scoped with
Sergey Ulanov
2013/02/22 21:04:06
Done.
| |
| 224 if (error && error != ERROR_HANDLE_EOF) | 217 if (error == ERROR_HANDLE_EOF) { |
| 225 result = RecordAndMapError(error, error_source_); | 218 result = IOResult(0, 0); |
| 226 | 219 } else if (error) { |
| 227 if (bytes_read) | 220 result = IOResult::FromOSError(error); |
| 221 RecordError(result, error_source_); | |
| 222 } else { | |
| 223 result = IOResult(bytes_read, 0); | |
| 228 IncrementOffset(&io_context_.overlapped, bytes_read); | 224 IncrementOffset(&io_context_.overlapped, bytes_read); |
| 225 } | |
| 229 | 226 |
| 230 CompletionCallback temp_callback = callback_; | 227 CompletionCallback temp_callback = callback_; |
| 231 callback_.Reset(); | 228 callback_.Reset(); |
| 232 scoped_refptr<IOBuffer> temp_buf = in_flight_buf_; | 229 scoped_refptr<IOBuffer> temp_buf = in_flight_buf_; |
| 233 in_flight_buf_ = NULL; | 230 in_flight_buf_ = NULL; |
| 234 temp_callback.Run(result); | 231 temp_callback.Run(result.result); |
| 235 } | 232 } |
| 236 | 233 |
| 237 } // namespace net | 234 } // namespace net |
| OLD | NEW |