| 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 "webkit/browser/fileapi/local_file_stream_writer.h" | 5 #include "storage/browser/fileapi/local_file_stream_writer.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 9 #include "net/base/file_stream.h" | 9 #include "net/base/file_stream.h" |
| 10 #include "net/base/io_buffer.h" | 10 #include "net/base/io_buffer.h" |
| 11 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
| 12 | 12 |
| 13 namespace fileapi { | 13 namespace storage { |
| 14 | 14 |
| 15 namespace { | 15 namespace { |
| 16 | 16 |
| 17 const int kOpenFlagsForWrite = base::File::FLAG_OPEN | | 17 const int kOpenFlagsForWrite = |
| 18 base::File::FLAG_WRITE | | 18 base::File::FLAG_OPEN | base::File::FLAG_WRITE | base::File::FLAG_ASYNC; |
| 19 base::File::FLAG_ASYNC; | 19 const int kCreateFlagsForWrite = |
| 20 const int kCreateFlagsForWrite = base::File::FLAG_CREATE | | 20 base::File::FLAG_CREATE | base::File::FLAG_WRITE | base::File::FLAG_ASYNC; |
| 21 base::File::FLAG_WRITE | | |
| 22 base::File::FLAG_ASYNC; | |
| 23 | 21 |
| 24 } // namespace | 22 } // namespace |
| 25 | 23 |
| 26 FileStreamWriter* FileStreamWriter::CreateForLocalFile( | 24 FileStreamWriter* FileStreamWriter::CreateForLocalFile( |
| 27 base::TaskRunner* task_runner, | 25 base::TaskRunner* task_runner, |
| 28 const base::FilePath& file_path, | 26 const base::FilePath& file_path, |
| 29 int64 initial_offset, | 27 int64 initial_offset, |
| 30 OpenOrCreate open_or_create) { | 28 OpenOrCreate open_or_create) { |
| 31 return new LocalFileStreamWriter( | 29 return new LocalFileStreamWriter( |
| 32 task_runner, file_path, initial_offset, open_or_create); | 30 task_runner, file_path, initial_offset, open_or_create); |
| 33 } | 31 } |
| 34 | 32 |
| 35 LocalFileStreamWriter::~LocalFileStreamWriter() { | 33 LocalFileStreamWriter::~LocalFileStreamWriter() { |
| 36 // Invalidate weak pointers so that we won't receive any callbacks from | 34 // Invalidate weak pointers so that we won't receive any callbacks from |
| 37 // in-flight stream operations, which might be triggered during the file close | 35 // in-flight stream operations, which might be triggered during the file close |
| 38 // in the FileStream destructor. | 36 // in the FileStream destructor. |
| 39 weak_factory_.InvalidateWeakPtrs(); | 37 weak_factory_.InvalidateWeakPtrs(); |
| 40 | 38 |
| 41 // FileStream's destructor closes the file safely, since we opened the file | 39 // FileStream's destructor closes the file safely, since we opened the file |
| 42 // by its Open() method. | 40 // by its Open() method. |
| 43 } | 41 } |
| 44 | 42 |
| 45 int LocalFileStreamWriter::Write(net::IOBuffer* buf, int buf_len, | 43 int LocalFileStreamWriter::Write(net::IOBuffer* buf, |
| 44 int buf_len, |
| 46 const net::CompletionCallback& callback) { | 45 const net::CompletionCallback& callback) { |
| 47 DCHECK(!has_pending_operation_); | 46 DCHECK(!has_pending_operation_); |
| 48 DCHECK(cancel_callback_.is_null()); | 47 DCHECK(cancel_callback_.is_null()); |
| 49 | 48 |
| 50 has_pending_operation_ = true; | 49 has_pending_operation_ = true; |
| 51 if (stream_impl_) { | 50 if (stream_impl_) { |
| 52 int result = InitiateWrite(buf, buf_len, callback); | 51 int result = InitiateWrite(buf, buf_len, callback); |
| 53 if (result != net::ERR_IO_PENDING) | 52 if (result != net::ERR_IO_PENDING) |
| 54 has_pending_operation_ = false; | 53 has_pending_operation_ = false; |
| 55 return result; | 54 return result; |
| 56 } | 55 } |
| 57 return InitiateOpen(callback, | 56 return InitiateOpen(callback, |
| 58 base::Bind(&LocalFileStreamWriter::ReadyToWrite, | 57 base::Bind(&LocalFileStreamWriter::ReadyToWrite, |
| 59 weak_factory_.GetWeakPtr(), | 58 weak_factory_.GetWeakPtr(), |
| 60 make_scoped_refptr(buf), buf_len, callback)); | 59 make_scoped_refptr(buf), |
| 60 buf_len, |
| 61 callback)); |
| 61 } | 62 } |
| 62 | 63 |
| 63 int LocalFileStreamWriter::Cancel(const net::CompletionCallback& callback) { | 64 int LocalFileStreamWriter::Cancel(const net::CompletionCallback& callback) { |
| 64 if (!has_pending_operation_) | 65 if (!has_pending_operation_) |
| 65 return net::ERR_UNEXPECTED; | 66 return net::ERR_UNEXPECTED; |
| 66 | 67 |
| 67 DCHECK(!callback.is_null()); | 68 DCHECK(!callback.is_null()); |
| 68 cancel_callback_ = callback; | 69 cancel_callback_ = callback; |
| 69 return net::ERR_IO_PENDING; | 70 return net::ERR_IO_PENDING; |
| 70 } | 71 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 86 | 87 |
| 87 LocalFileStreamWriter::LocalFileStreamWriter(base::TaskRunner* task_runner, | 88 LocalFileStreamWriter::LocalFileStreamWriter(base::TaskRunner* task_runner, |
| 88 const base::FilePath& file_path, | 89 const base::FilePath& file_path, |
| 89 int64 initial_offset, | 90 int64 initial_offset, |
| 90 OpenOrCreate open_or_create) | 91 OpenOrCreate open_or_create) |
| 91 : file_path_(file_path), | 92 : file_path_(file_path), |
| 92 open_or_create_(open_or_create), | 93 open_or_create_(open_or_create), |
| 93 initial_offset_(initial_offset), | 94 initial_offset_(initial_offset), |
| 94 task_runner_(task_runner), | 95 task_runner_(task_runner), |
| 95 has_pending_operation_(false), | 96 has_pending_operation_(false), |
| 96 weak_factory_(this) {} | 97 weak_factory_(this) { |
| 98 } |
| 97 | 99 |
| 98 int LocalFileStreamWriter::InitiateOpen( | 100 int LocalFileStreamWriter::InitiateOpen( |
| 99 const net::CompletionCallback& error_callback, | 101 const net::CompletionCallback& error_callback, |
| 100 const base::Closure& main_operation) { | 102 const base::Closure& main_operation) { |
| 101 DCHECK(has_pending_operation_); | 103 DCHECK(has_pending_operation_); |
| 102 DCHECK(!stream_impl_.get()); | 104 DCHECK(!stream_impl_.get()); |
| 103 | 105 |
| 104 stream_impl_.reset(new net::FileStream(task_runner_)); | 106 stream_impl_.reset(new net::FileStream(task_runner_)); |
| 105 | 107 |
| 106 int open_flags = 0; | 108 int open_flags = 0; |
| 107 switch (open_or_create_) { | 109 switch (open_or_create_) { |
| 108 case OPEN_EXISTING_FILE: | 110 case OPEN_EXISTING_FILE: |
| 109 open_flags = kOpenFlagsForWrite; | 111 open_flags = kOpenFlagsForWrite; |
| 110 break; | 112 break; |
| 111 case CREATE_NEW_FILE: | 113 case CREATE_NEW_FILE: |
| 112 open_flags = kCreateFlagsForWrite; | 114 open_flags = kCreateFlagsForWrite; |
| 113 break; | 115 break; |
| 114 } | 116 } |
| 115 | 117 |
| 116 return stream_impl_->Open(file_path_, | 118 return stream_impl_->Open(file_path_, |
| 117 open_flags, | 119 open_flags, |
| 118 base::Bind(&LocalFileStreamWriter::DidOpen, | 120 base::Bind(&LocalFileStreamWriter::DidOpen, |
| 119 weak_factory_.GetWeakPtr(), | 121 weak_factory_.GetWeakPtr(), |
| 120 error_callback, | 122 error_callback, |
| 121 main_operation)); | 123 main_operation)); |
| 122 } | 124 } |
| 123 | 125 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 146 const base::Closure& main_operation) { | 148 const base::Closure& main_operation) { |
| 147 DCHECK(has_pending_operation_); | 149 DCHECK(has_pending_operation_); |
| 148 DCHECK(stream_impl_.get()); | 150 DCHECK(stream_impl_.get()); |
| 149 | 151 |
| 150 if (initial_offset_ == 0) { | 152 if (initial_offset_ == 0) { |
| 151 // No need to seek. | 153 // No need to seek. |
| 152 main_operation.Run(); | 154 main_operation.Run(); |
| 153 return; | 155 return; |
| 154 } | 156 } |
| 155 | 157 |
| 156 int result = stream_impl_->Seek(base::File::FROM_BEGIN, initial_offset_, | 158 int result = stream_impl_->Seek(base::File::FROM_BEGIN, |
| 159 initial_offset_, |
| 157 base::Bind(&LocalFileStreamWriter::DidSeek, | 160 base::Bind(&LocalFileStreamWriter::DidSeek, |
| 158 weak_factory_.GetWeakPtr(), | 161 weak_factory_.GetWeakPtr(), |
| 159 error_callback, | 162 error_callback, |
| 160 main_operation)); | 163 main_operation)); |
| 161 if (result != net::ERR_IO_PENDING) { | 164 if (result != net::ERR_IO_PENDING) { |
| 162 has_pending_operation_ = false; | 165 has_pending_operation_ = false; |
| 163 error_callback.Run(result); | 166 error_callback.Run(result); |
| 164 } | 167 } |
| 165 } | 168 } |
| 166 | 169 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 181 if (result < 0) { | 184 if (result < 0) { |
| 182 has_pending_operation_ = false; | 185 has_pending_operation_ = false; |
| 183 error_callback.Run(static_cast<int>(result)); | 186 error_callback.Run(static_cast<int>(result)); |
| 184 return; | 187 return; |
| 185 } | 188 } |
| 186 | 189 |
| 187 main_operation.Run(); | 190 main_operation.Run(); |
| 188 } | 191 } |
| 189 | 192 |
| 190 void LocalFileStreamWriter::ReadyToWrite( | 193 void LocalFileStreamWriter::ReadyToWrite( |
| 191 net::IOBuffer* buf, int buf_len, | 194 net::IOBuffer* buf, |
| 195 int buf_len, |
| 192 const net::CompletionCallback& callback) { | 196 const net::CompletionCallback& callback) { |
| 193 DCHECK(has_pending_operation_); | 197 DCHECK(has_pending_operation_); |
| 194 | 198 |
| 195 int result = InitiateWrite(buf, buf_len, callback); | 199 int result = InitiateWrite(buf, buf_len, callback); |
| 196 if (result != net::ERR_IO_PENDING) { | 200 if (result != net::ERR_IO_PENDING) { |
| 197 has_pending_operation_ = false; | 201 has_pending_operation_ = false; |
| 198 callback.Run(result); | 202 callback.Run(result); |
| 199 } | 203 } |
| 200 } | 204 } |
| 201 | 205 |
| 202 int LocalFileStreamWriter::InitiateWrite( | 206 int LocalFileStreamWriter::InitiateWrite( |
| 203 net::IOBuffer* buf, int buf_len, | 207 net::IOBuffer* buf, |
| 208 int buf_len, |
| 204 const net::CompletionCallback& callback) { | 209 const net::CompletionCallback& callback) { |
| 205 DCHECK(has_pending_operation_); | 210 DCHECK(has_pending_operation_); |
| 206 DCHECK(stream_impl_.get()); | 211 DCHECK(stream_impl_.get()); |
| 207 | 212 |
| 208 return stream_impl_->Write(buf, buf_len, | 213 return stream_impl_->Write(buf, |
| 214 buf_len, |
| 209 base::Bind(&LocalFileStreamWriter::DidWrite, | 215 base::Bind(&LocalFileStreamWriter::DidWrite, |
| 210 weak_factory_.GetWeakPtr(), | 216 weak_factory_.GetWeakPtr(), |
| 211 callback)); | 217 callback)); |
| 212 } | 218 } |
| 213 | 219 |
| 214 void LocalFileStreamWriter::DidWrite(const net::CompletionCallback& callback, | 220 void LocalFileStreamWriter::DidWrite(const net::CompletionCallback& callback, |
| 215 int result) { | 221 int result) { |
| 216 DCHECK(has_pending_operation_); | 222 DCHECK(has_pending_operation_); |
| 217 | 223 |
| 218 if (CancelIfRequested()) | 224 if (CancelIfRequested()) |
| 219 return; | 225 return; |
| 220 has_pending_operation_ = false; | 226 has_pending_operation_ = false; |
| 221 callback.Run(result); | 227 callback.Run(result); |
| 222 } | 228 } |
| 223 | 229 |
| 224 int LocalFileStreamWriter::InitiateFlush( | 230 int LocalFileStreamWriter::InitiateFlush( |
| 225 const net::CompletionCallback& callback) { | 231 const net::CompletionCallback& callback) { |
| 226 DCHECK(has_pending_operation_); | 232 DCHECK(has_pending_operation_); |
| 227 DCHECK(stream_impl_.get()); | 233 DCHECK(stream_impl_.get()); |
| 228 | 234 |
| 229 return stream_impl_->Flush(base::Bind(&LocalFileStreamWriter::DidFlush, | 235 return stream_impl_->Flush(base::Bind( |
| 230 weak_factory_.GetWeakPtr(), | 236 &LocalFileStreamWriter::DidFlush, weak_factory_.GetWeakPtr(), callback)); |
| 231 callback)); | |
| 232 } | 237 } |
| 233 | 238 |
| 234 void LocalFileStreamWriter::DidFlush(const net::CompletionCallback& callback, | 239 void LocalFileStreamWriter::DidFlush(const net::CompletionCallback& callback, |
| 235 int result) { | 240 int result) { |
| 236 DCHECK(has_pending_operation_); | 241 DCHECK(has_pending_operation_); |
| 237 | 242 |
| 238 if (CancelIfRequested()) | 243 if (CancelIfRequested()) |
| 239 return; | 244 return; |
| 240 has_pending_operation_ = false; | 245 has_pending_operation_ = false; |
| 241 callback.Run(result); | 246 callback.Run(result); |
| 242 } | 247 } |
| 243 | 248 |
| 244 bool LocalFileStreamWriter::CancelIfRequested() { | 249 bool LocalFileStreamWriter::CancelIfRequested() { |
| 245 DCHECK(has_pending_operation_); | 250 DCHECK(has_pending_operation_); |
| 246 | 251 |
| 247 if (cancel_callback_.is_null()) | 252 if (cancel_callback_.is_null()) |
| 248 return false; | 253 return false; |
| 249 | 254 |
| 250 net::CompletionCallback pending_cancel = cancel_callback_; | 255 net::CompletionCallback pending_cancel = cancel_callback_; |
| 251 has_pending_operation_ = false; | 256 has_pending_operation_ = false; |
| 252 cancel_callback_.Reset(); | 257 cancel_callback_.Reset(); |
| 253 pending_cancel.Run(net::OK); | 258 pending_cancel.Run(net::OK); |
| 254 return true; | 259 return true; |
| 255 } | 260 } |
| 256 | 261 |
| 257 } // namespace fileapi | 262 } // namespace storage |
| OLD | NEW |