Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Side by Side Diff: webkit/fileapi/local_file_stream_writer.cc

Issue 15859007: Move browser-specific FileAPI code from webkit/fileapi to webkit/browser/fileapi (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: dump_file_system build fix Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "webkit/fileapi/local_file_stream_writer.h"
6
7 #include "base/callback.h"
8 #include "base/message_loop.h"
9 #include "net/base/file_stream.h"
10 #include "net/base/io_buffer.h"
11 #include "net/base/net_errors.h"
12
13 namespace fileapi {
14
15 namespace {
16
17 const int kOpenFlagsForWrite = base::PLATFORM_FILE_OPEN |
18 base::PLATFORM_FILE_WRITE |
19 base::PLATFORM_FILE_ASYNC;
20
21 } // namespace
22
23 LocalFileStreamWriter::LocalFileStreamWriter(const base::FilePath& file_path,
24 int64 initial_offset)
25 : file_path_(file_path),
26 initial_offset_(initial_offset),
27 has_pending_operation_(false),
28 weak_factory_(this) {}
29
30 LocalFileStreamWriter::~LocalFileStreamWriter() {
31 // Invalidate weak pointers so that we won't receive any callbacks from
32 // in-flight stream operations, which might be triggered during the file close
33 // in the FileStream destructor.
34 weak_factory_.InvalidateWeakPtrs();
35
36 // FileStream's destructor closes the file safely, since we opened the file
37 // by its Open() method.
38 }
39
40 int LocalFileStreamWriter::Write(net::IOBuffer* buf, int buf_len,
41 const net::CompletionCallback& callback) {
42 DCHECK(!has_pending_operation_);
43 DCHECK(cancel_callback_.is_null());
44
45 has_pending_operation_ = true;
46 if (stream_impl_) {
47 int result = InitiateWrite(buf, buf_len, callback);
48 if (result != net::ERR_IO_PENDING)
49 has_pending_operation_ = false;
50 return result;
51 }
52 return InitiateOpen(callback,
53 base::Bind(&LocalFileStreamWriter::ReadyToWrite,
54 weak_factory_.GetWeakPtr(),
55 make_scoped_refptr(buf), buf_len, callback));
56 }
57
58 int LocalFileStreamWriter::Cancel(const net::CompletionCallback& callback) {
59 if (!has_pending_operation_)
60 return net::ERR_UNEXPECTED;
61
62 DCHECK(!callback.is_null());
63 cancel_callback_ = callback;
64 return net::ERR_IO_PENDING;
65 }
66
67 int LocalFileStreamWriter::Flush(const net::CompletionCallback& callback) {
68 DCHECK(!has_pending_operation_);
69 DCHECK(cancel_callback_.is_null());
70
71 // Write() is not called yet, so there's nothing to flush.
72 if (!stream_impl_)
73 return net::OK;
74
75 has_pending_operation_ = true;
76 int result = InitiateFlush(callback);
77 if (result != net::ERR_IO_PENDING)
78 has_pending_operation_ = false;
79 return result;
80 }
81
82 int LocalFileStreamWriter::InitiateOpen(
83 const net::CompletionCallback& error_callback,
84 const base::Closure& main_operation) {
85 DCHECK(has_pending_operation_);
86 DCHECK(!stream_impl_.get());
87
88 stream_impl_.reset(new net::FileStream(NULL));
89 return stream_impl_->Open(file_path_,
90 kOpenFlagsForWrite,
91 base::Bind(&LocalFileStreamWriter::DidOpen,
92 weak_factory_.GetWeakPtr(),
93 error_callback,
94 main_operation));
95 }
96
97 void LocalFileStreamWriter::DidOpen(
98 const net::CompletionCallback& error_callback,
99 const base::Closure& main_operation,
100 int result) {
101 DCHECK(has_pending_operation_);
102 DCHECK(stream_impl_.get());
103
104 if (CancelIfRequested())
105 return;
106
107 if (result != net::OK) {
108 has_pending_operation_ = false;
109 stream_impl_.reset(NULL);
110 error_callback.Run(result);
111 return;
112 }
113
114 InitiateSeek(error_callback, main_operation);
115 }
116
117 void LocalFileStreamWriter::InitiateSeek(
118 const net::CompletionCallback& error_callback,
119 const base::Closure& main_operation) {
120 DCHECK(has_pending_operation_);
121 DCHECK(stream_impl_.get());
122
123 if (initial_offset_ == 0) {
124 // No need to seek.
125 main_operation.Run();
126 return;
127 }
128
129 int result = stream_impl_->Seek(net::FROM_BEGIN, initial_offset_,
130 base::Bind(&LocalFileStreamWriter::DidSeek,
131 weak_factory_.GetWeakPtr(),
132 error_callback,
133 main_operation));
134 if (result != net::ERR_IO_PENDING) {
135 has_pending_operation_ = false;
136 error_callback.Run(result);
137 }
138 }
139
140 void LocalFileStreamWriter::DidSeek(
141 const net::CompletionCallback& error_callback,
142 const base::Closure& main_operation,
143 int64 result) {
144 DCHECK(has_pending_operation_);
145
146 if (CancelIfRequested())
147 return;
148
149 if (result != initial_offset_) {
150 // TODO(kinaba) add a more specific error code.
151 result = net::ERR_FAILED;
152 }
153
154 if (result < 0) {
155 has_pending_operation_ = false;
156 error_callback.Run(static_cast<int>(result));
157 return;
158 }
159
160 main_operation.Run();
161 }
162
163 void LocalFileStreamWriter::ReadyToWrite(
164 net::IOBuffer* buf, int buf_len,
165 const net::CompletionCallback& callback) {
166 DCHECK(has_pending_operation_);
167
168 int result = InitiateWrite(buf, buf_len, callback);
169 if (result != net::ERR_IO_PENDING) {
170 has_pending_operation_ = false;
171 callback.Run(result);
172 }
173 }
174
175 int LocalFileStreamWriter::InitiateWrite(
176 net::IOBuffer* buf, int buf_len,
177 const net::CompletionCallback& callback) {
178 DCHECK(has_pending_operation_);
179 DCHECK(stream_impl_.get());
180
181 return stream_impl_->Write(buf, buf_len,
182 base::Bind(&LocalFileStreamWriter::DidWrite,
183 weak_factory_.GetWeakPtr(),
184 callback));
185 }
186
187 void LocalFileStreamWriter::DidWrite(const net::CompletionCallback& callback,
188 int result) {
189 DCHECK(has_pending_operation_);
190
191 if (CancelIfRequested())
192 return;
193 has_pending_operation_ = false;
194 callback.Run(result);
195 }
196
197 int LocalFileStreamWriter::InitiateFlush(
198 const net::CompletionCallback& callback) {
199 DCHECK(has_pending_operation_);
200 DCHECK(stream_impl_.get());
201
202 return stream_impl_->Flush(base::Bind(&LocalFileStreamWriter::DidFlush,
203 weak_factory_.GetWeakPtr(),
204 callback));
205 }
206
207 void LocalFileStreamWriter::DidFlush(const net::CompletionCallback& callback,
208 int result) {
209 DCHECK(has_pending_operation_);
210
211 if (CancelIfRequested())
212 return;
213 has_pending_operation_ = false;
214 callback.Run(result);
215 }
216
217 bool LocalFileStreamWriter::CancelIfRequested() {
218 DCHECK(has_pending_operation_);
219
220 if (cancel_callback_.is_null())
221 return false;
222
223 net::CompletionCallback pending_cancel = cancel_callback_;
224 has_pending_operation_ = false;
225 cancel_callback_.Reset();
226 pending_cancel.Run(net::OK);
227 return true;
228 }
229
230 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/fileapi/local_file_stream_writer.h ('k') | webkit/fileapi/local_file_stream_writer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698