net cleanup: Remove unnecessary namespace prefixes.
[chromium-blink-merge.git] / storage / browser / fileapi / local_file_stream_writer.cc
blob0eb555f9262127cef9c617dba3210797e0020c61
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
3 // found in the LICENSE file.
5 #include "storage/browser/fileapi/local_file_stream_writer.h"
7 #include "base/callback.h"
8 #include "base/message_loop/message_loop.h"
9 #include "net/base/file_stream.h"
10 #include "net/base/io_buffer.h"
11 #include "net/base/net_errors.h"
13 namespace storage {
15 namespace {
17 const int kOpenFlagsForWrite = base::File::FLAG_OPEN |
18 base::File::FLAG_WRITE |
19 base::File::FLAG_ASYNC;
20 const int kCreateFlagsForWrite = base::File::FLAG_CREATE |
21 base::File::FLAG_WRITE |
22 base::File::FLAG_ASYNC;
24 } // namespace
26 FileStreamWriter* FileStreamWriter::CreateForLocalFile(
27 base::TaskRunner* task_runner,
28 const base::FilePath& file_path,
29 int64 initial_offset,
30 OpenOrCreate open_or_create) {
31 return new LocalFileStreamWriter(
32 task_runner, file_path, initial_offset, open_or_create);
35 LocalFileStreamWriter::~LocalFileStreamWriter() {
36 // 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
38 // in the FileStream destructor.
39 weak_factory_.InvalidateWeakPtrs();
41 // FileStream's destructor closes the file safely, since we opened the file
42 // by its Open() method.
45 int LocalFileStreamWriter::Write(net::IOBuffer* buf, int buf_len,
46 const net::CompletionCallback& callback) {
47 DCHECK(!has_pending_operation_);
48 DCHECK(cancel_callback_.is_null());
50 has_pending_operation_ = true;
51 if (stream_impl_) {
52 int result = InitiateWrite(buf, buf_len, callback);
53 if (result != net::ERR_IO_PENDING)
54 has_pending_operation_ = false;
55 return result;
57 return InitiateOpen(callback,
58 base::Bind(&LocalFileStreamWriter::ReadyToWrite,
59 weak_factory_.GetWeakPtr(),
60 make_scoped_refptr(buf), buf_len, callback));
63 int LocalFileStreamWriter::Cancel(const net::CompletionCallback& callback) {
64 if (!has_pending_operation_)
65 return net::ERR_UNEXPECTED;
67 DCHECK(!callback.is_null());
68 cancel_callback_ = callback;
69 return net::ERR_IO_PENDING;
72 int LocalFileStreamWriter::Flush(const net::CompletionCallback& callback) {
73 DCHECK(!has_pending_operation_);
74 DCHECK(cancel_callback_.is_null());
76 // Write() is not called yet, so there's nothing to flush.
77 if (!stream_impl_)
78 return net::OK;
80 has_pending_operation_ = true;
81 int result = InitiateFlush(callback);
82 if (result != net::ERR_IO_PENDING)
83 has_pending_operation_ = false;
84 return result;
87 LocalFileStreamWriter::LocalFileStreamWriter(base::TaskRunner* task_runner,
88 const base::FilePath& file_path,
89 int64 initial_offset,
90 OpenOrCreate open_or_create)
91 : file_path_(file_path),
92 open_or_create_(open_or_create),
93 initial_offset_(initial_offset),
94 task_runner_(task_runner),
95 has_pending_operation_(false),
96 weak_factory_(this) {}
98 int LocalFileStreamWriter::InitiateOpen(
99 const net::CompletionCallback& error_callback,
100 const base::Closure& main_operation) {
101 DCHECK(has_pending_operation_);
102 DCHECK(!stream_impl_.get());
104 stream_impl_.reset(new net::FileStream(task_runner_));
106 int open_flags = 0;
107 switch (open_or_create_) {
108 case OPEN_EXISTING_FILE:
109 open_flags = kOpenFlagsForWrite;
110 break;
111 case CREATE_NEW_FILE:
112 open_flags = kCreateFlagsForWrite;
113 break;
116 return stream_impl_->Open(file_path_,
117 open_flags,
118 base::Bind(&LocalFileStreamWriter::DidOpen,
119 weak_factory_.GetWeakPtr(),
120 error_callback,
121 main_operation));
124 void LocalFileStreamWriter::DidOpen(
125 const net::CompletionCallback& error_callback,
126 const base::Closure& main_operation,
127 int result) {
128 DCHECK(has_pending_operation_);
129 DCHECK(stream_impl_.get());
131 if (CancelIfRequested())
132 return;
134 if (result != net::OK) {
135 has_pending_operation_ = false;
136 stream_impl_.reset(NULL);
137 error_callback.Run(result);
138 return;
141 InitiateSeek(error_callback, main_operation);
144 void LocalFileStreamWriter::InitiateSeek(
145 const net::CompletionCallback& error_callback,
146 const base::Closure& main_operation) {
147 DCHECK(has_pending_operation_);
148 DCHECK(stream_impl_.get());
150 if (initial_offset_ == 0) {
151 // No need to seek.
152 main_operation.Run();
153 return;
156 int result = stream_impl_->Seek(base::File::FROM_BEGIN, initial_offset_,
157 base::Bind(&LocalFileStreamWriter::DidSeek,
158 weak_factory_.GetWeakPtr(),
159 error_callback,
160 main_operation));
161 if (result != net::ERR_IO_PENDING) {
162 has_pending_operation_ = false;
163 error_callback.Run(result);
167 void LocalFileStreamWriter::DidSeek(
168 const net::CompletionCallback& error_callback,
169 const base::Closure& main_operation,
170 int64 result) {
171 DCHECK(has_pending_operation_);
173 if (CancelIfRequested())
174 return;
176 if (result != initial_offset_) {
177 // TODO(kinaba) add a more specific error code.
178 result = net::ERR_FAILED;
181 if (result < 0) {
182 has_pending_operation_ = false;
183 error_callback.Run(static_cast<int>(result));
184 return;
187 main_operation.Run();
190 void LocalFileStreamWriter::ReadyToWrite(
191 net::IOBuffer* buf, int buf_len,
192 const net::CompletionCallback& callback) {
193 DCHECK(has_pending_operation_);
195 int result = InitiateWrite(buf, buf_len, callback);
196 if (result != net::ERR_IO_PENDING) {
197 has_pending_operation_ = false;
198 callback.Run(result);
202 int LocalFileStreamWriter::InitiateWrite(
203 net::IOBuffer* buf, int buf_len,
204 const net::CompletionCallback& callback) {
205 DCHECK(has_pending_operation_);
206 DCHECK(stream_impl_.get());
208 return stream_impl_->Write(buf, buf_len,
209 base::Bind(&LocalFileStreamWriter::DidWrite,
210 weak_factory_.GetWeakPtr(),
211 callback));
214 void LocalFileStreamWriter::DidWrite(const net::CompletionCallback& callback,
215 int result) {
216 DCHECK(has_pending_operation_);
218 if (CancelIfRequested())
219 return;
220 has_pending_operation_ = false;
221 callback.Run(result);
224 int LocalFileStreamWriter::InitiateFlush(
225 const net::CompletionCallback& callback) {
226 DCHECK(has_pending_operation_);
227 DCHECK(stream_impl_.get());
229 return stream_impl_->Flush(base::Bind(&LocalFileStreamWriter::DidFlush,
230 weak_factory_.GetWeakPtr(),
231 callback));
234 void LocalFileStreamWriter::DidFlush(const net::CompletionCallback& callback,
235 int result) {
236 DCHECK(has_pending_operation_);
238 if (CancelIfRequested())
239 return;
240 has_pending_operation_ = false;
241 callback.Run(result);
244 bool LocalFileStreamWriter::CancelIfRequested() {
245 DCHECK(has_pending_operation_);
247 if (cancel_callback_.is_null())
248 return false;
250 net::CompletionCallback pending_cancel = cancel_callback_;
251 has_pending_operation_ = false;
252 cancel_callback_.Reset();
253 pending_cancel.Run(net::OK);
254 return true;
257 } // namespace storage