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

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

Issue 10126004: fileapi: FileWriter and LocalFileWriter. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Drop Seek(), loosen Cancel() and destructor's requirements, and add constuctor parameters. Created 8 years, 8 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_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
12 namespace fileapi {
13
14 namespace {
15
16 const int kOpenFlagsForWrite = base::PLATFORM_FILE_OPEN |
17 base::PLATFORM_FILE_WRITE |
18 base::PLATFORM_FILE_ASYNC;
19
20 const int kOpenFlagsForCreate = base::PLATFORM_FILE_CREATE_ALWAYS |
21 base::PLATFORM_FILE_WRITE |
22 base::PLATFORM_FILE_ASYNC;
23
24 } // namespace
25
26 LocalFileWriter::LocalFileWriter(const FilePath& file_path,
27 int64 initial_offset,
28 FileOpenMode mode)
29 : file_path_(file_path),
30 file_open_flags_(mode == CREATE ? kOpenFlagsForCreate
31 : kOpenFlagsForWrite),
32 initial_offset_(initial_offset),
33 has_pending_operation_(false),
34 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {}
35
36 LocalFileWriter::~LocalFileWriter() {
37 // Invalidate weak pointers so that we won't receive any callbacks from
38 // in-flight stream operations, which might be triggered during the file close
39 // in the FileStream destructor.
40 weak_factory_.InvalidateWeakPtrs();
41
42 // FileStream's destructor closes the file safely, since we opened the file
43 // by its Open() method.
44 }
45
46 int LocalFileWriter::Write(net::IOBuffer* buf, int buf_len,
47 const net::CompletionCallback& callback) {
48 DCHECK(!has_pending_operation_);
49 DCHECK(cancel_callback_.is_null());
50
51 has_pending_operation_ = true;
52 if (stream_impl_.get()) {
53 int result = InitiateWrite(buf, buf_len, callback);
54 if (result != net::ERR_IO_PENDING)
55 has_pending_operation_ = false;
56 return result;
57 }
58 return InitiateOpen(callback,
59 base::Bind(&LocalFileWriter::ReadyToWrite,
60 weak_factory_.GetWeakPtr(),
61 make_scoped_refptr(buf), buf_len, callback));
62 }
63
64 void LocalFileWriter::Cancel(const net::CompletionCallback& callback) {
65 if (!has_pending_operation_) {
66 MessageLoop::current()->PostTask(FROM_HERE,
67 base::Bind(callback, net::ERR_FAILED));
68 return;
69 }
70
71 DCHECK(!callback.is_null());
72 cancel_callback_ = callback;
73 }
74
75 int LocalFileWriter::InitiateOpen(const net::CompletionCallback& error_callback,
76 const base::Closure& main_operation) {
77 DCHECK(has_pending_operation_);
78 DCHECK(!stream_impl_.get());
79
80 stream_impl_.reset(new net::FileStream(NULL));
81 return stream_impl_->Open(file_path_,
82 file_open_flags_,
83 base::Bind(&LocalFileWriter::DidOpen,
84 weak_factory_.GetWeakPtr(),
85 error_callback,
86 main_operation));
87 }
88
89 void LocalFileWriter::DidOpen(const net::CompletionCallback& error_callback,
90 const base::Closure& main_operation,
91 int result) {
92 DCHECK(has_pending_operation_);
93 DCHECK(stream_impl_.get());
94
95 if (CancelIfRequested())
96 return;
97
98 if (result != net::OK) {
99 has_pending_operation_ = false;
100 stream_impl_.reset(NULL);
101 error_callback.Run(result);
102 return;
103 }
104
105 InitiateSeek(error_callback, main_operation);
106 }
107
108 void LocalFileWriter::InitiateSeek(
109 const net::CompletionCallback& error_callback,
110 const base::Closure& main_operation) {
111 DCHECK(has_pending_operation_);
112 DCHECK(stream_impl_.get());
113
114 if (initial_offset_ == 0) {
115 // No need to seek.
116 main_operation.Run();
kinuko 2012/04/23 09:29:57 nit: could we return here earlier?
kinaba 2012/04/23 10:55:14 Done.
117 } else {
118 int result = stream_impl_->Seek(net::FROM_BEGIN, initial_offset_,
119 base::Bind(&LocalFileWriter::DidSeek,
120 weak_factory_.GetWeakPtr(),
121 error_callback,
122 main_operation));
123 if (result != net::ERR_IO_PENDING) {
124 has_pending_operation_ = false;
125 error_callback.Run(result);
126 }
127 }
128 }
129
130 void LocalFileWriter::DidSeek(const net::CompletionCallback& error_callback,
131 const base::Closure& main_operation,
132 int64 result) {
133 DCHECK(has_pending_operation_);
134
135 if (CancelIfRequested())
136 return;
137
138 if (result < 0) {
139 has_pending_operation_ = false;
140 error_callback.Run(static_cast<int>(result));
141 return;
142 }
143
kinuko 2012/04/23 09:29:57 Seek returns the new offset and in most cases we'd
kinaba 2012/04/23 10:55:14 Modified to check the equality and to return net::
144 main_operation.Run();
145 }
146
147 void LocalFileWriter::ReadyToWrite(net::IOBuffer* buf, int buf_len,
148 const net::CompletionCallback& callback) {
149 DCHECK(has_pending_operation_);
150
151 int result = InitiateWrite(buf, buf_len, callback);
152 if (result != net::ERR_IO_PENDING) {
153 has_pending_operation_ = false;
154 callback.Run(result);
155 }
156 }
157
158 int LocalFileWriter::InitiateWrite(net::IOBuffer* buf, int buf_len,
159 const net::CompletionCallback& callback) {
160 DCHECK(has_pending_operation_);
161 DCHECK(stream_impl_.get());
162
163 return stream_impl_->Write(buf, buf_len,
164 base::Bind(&LocalFileWriter::DidWrite,
165 weak_factory_.GetWeakPtr(),
166 callback));
167 }
168
169 void LocalFileWriter::DidWrite(const net::CompletionCallback& callback,
170 int result) {
171 DCHECK(has_pending_operation_);
172
173 if (CancelIfRequested())
174 return;
175 has_pending_operation_ = false;
176 callback.Run(result);
177 }
178
179 bool LocalFileWriter::CancelIfRequested() {
180 DCHECK(has_pending_operation_);
181
182 if (cancel_callback_.is_null())
183 return false;
184
185 net::CompletionCallback pending_cancel = cancel_callback_;
186 has_pending_operation_ = false;
187 cancel_callback_.Reset();
188 pending_cancel.Run(net::OK);
189 return true;
190 }
191
192 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698