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; |
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; |
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 int result; |
224 if (error && error != ERROR_HANDLE_EOF) | 217 if (error == ERROR_HANDLE_EOF) { |
225 result = RecordAndMapError(error, error_source_); | 218 result = 0; |
226 | 219 } else if (error) { |
227 if (bytes_read) | 220 IOResult error_result = IOResult::FromOSError(error); |
| 221 RecordError(error_result, error_source_); |
| 222 result = error_result.result; |
| 223 } else { |
| 224 result = bytes_read; |
228 IncrementOffset(&io_context_.overlapped, bytes_read); | 225 IncrementOffset(&io_context_.overlapped, bytes_read); |
| 226 } |
229 | 227 |
230 CompletionCallback temp_callback = callback_; | 228 CompletionCallback temp_callback = callback_; |
231 callback_.Reset(); | 229 callback_.Reset(); |
232 scoped_refptr<IOBuffer> temp_buf = in_flight_buf_; | 230 scoped_refptr<IOBuffer> temp_buf = in_flight_buf_; |
233 in_flight_buf_ = NULL; | 231 in_flight_buf_ = NULL; |
234 temp_callback.Run(result); | 232 temp_callback.Run(result); |
235 } | 233 } |
236 | 234 |
237 } // namespace net | 235 } // namespace net |
OLD | NEW |