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

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: Reflect review. 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 int LocalFileWriter::Cancel(const net::CompletionCallback& callback) {
65 if (!has_pending_operation_)
66 return net::ERR_UNEXPECTED;
67
68 DCHECK(!callback.is_null());
69 cancel_callback_ = callback;
70 return net::ERR_IO_PENDING;
71 }
72
73 int LocalFileWriter::InitiateOpen(const net::CompletionCallback& error_callback,
74 const base::Closure& main_operation) {
75 DCHECK(has_pending_operation_);
76 DCHECK(!stream_impl_.get());
77
78 stream_impl_.reset(new net::FileStream(NULL));
79 return stream_impl_->Open(file_path_,
80 file_open_flags_,
81 base::Bind(&LocalFileWriter::DidOpen,
82 weak_factory_.GetWeakPtr(),
83 error_callback,
84 main_operation));
85 }
86
87 void LocalFileWriter::DidOpen(const net::CompletionCallback& error_callback,
88 const base::Closure& main_operation,
89 int result) {
90 DCHECK(has_pending_operation_);
91 DCHECK(stream_impl_.get());
92
93 if (CancelIfRequested())
94 return;
95
96 if (result != net::OK) {
97 has_pending_operation_ = false;
98 stream_impl_.reset(NULL);
99 error_callback.Run(result);
100 return;
101 }
102
103 InitiateSeek(error_callback, main_operation);
104 }
105
106 void LocalFileWriter::InitiateSeek(
107 const net::CompletionCallback& error_callback,
108 const base::Closure& main_operation) {
109 DCHECK(has_pending_operation_);
110 DCHECK(stream_impl_.get());
111
112 if (initial_offset_ == 0) {
113 // No need to seek.
114 main_operation.Run();
115 return;
116 }
117
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 void LocalFileWriter::DidSeek(const net::CompletionCallback& error_callback,
130 const base::Closure& main_operation,
131 int64 result) {
132 DCHECK(has_pending_operation_);
133
134 if (CancelIfRequested())
135 return;
136
137 if (result != initial_offset_)
138 result = net::ERR_INVALID_ARGUMENT;
kinuko 2012/04/23 12:50:29 This is not necessarily the given argument is inva
kinaba 2012/04/24 07:35:04 Done.
139
140 if (result < 0) {
141 has_pending_operation_ = false;
142 error_callback.Run(static_cast<int>(result));
143 return;
144 }
145
146 main_operation.Run();
147 }
148
149 void LocalFileWriter::ReadyToWrite(net::IOBuffer* buf, int buf_len,
150 const net::CompletionCallback& callback) {
151 DCHECK(has_pending_operation_);
152
153 int result = InitiateWrite(buf, buf_len, callback);
154 if (result != net::ERR_IO_PENDING) {
155 has_pending_operation_ = false;
156 callback.Run(result);
157 }
158 }
159
160 int LocalFileWriter::InitiateWrite(net::IOBuffer* buf, int buf_len,
161 const net::CompletionCallback& callback) {
162 DCHECK(has_pending_operation_);
163 DCHECK(stream_impl_.get());
164
165 return stream_impl_->Write(buf, buf_len,
166 base::Bind(&LocalFileWriter::DidWrite,
167 weak_factory_.GetWeakPtr(),
168 callback));
169 }
170
171 void LocalFileWriter::DidWrite(const net::CompletionCallback& callback,
172 int result) {
173 DCHECK(has_pending_operation_);
174
175 if (CancelIfRequested())
176 return;
177 has_pending_operation_ = false;
178 callback.Run(result);
179 }
180
181 bool LocalFileWriter::CancelIfRequested() {
182 DCHECK(has_pending_operation_);
183
184 if (cancel_callback_.is_null())
185 return false;
186
187 net::CompletionCallback pending_cancel = cancel_callback_;
188 has_pending_operation_ = false;
189 cancel_callback_.Reset();
190 pending_cancel.Run(net::OK);
191 return true;
192 }
193
194 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698