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

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 CREAET_OR_TRUNCATE mode. 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 } // namespace
21
22 LocalFileWriter::LocalFileWriter(const FilePath& file_path,
23 int64 initial_offset)
24 : file_path_(file_path),
25 initial_offset_(initial_offset),
26 has_pending_operation_(false),
27 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {}
28
29 LocalFileWriter::~LocalFileWriter() {
30 // Invalidate weak pointers so that we won't receive any callbacks from
31 // in-flight stream operations, which might be triggered during the file close
32 // in the FileStream destructor.
33 weak_factory_.InvalidateWeakPtrs();
34
35 // FileStream's destructor closes the file safely, since we opened the file
36 // by its Open() method.
37 }
38
39 int LocalFileWriter::Write(net::IOBuffer* buf, int buf_len,
40 const net::CompletionCallback& callback) {
41 DCHECK(!has_pending_operation_);
42 DCHECK(cancel_callback_.is_null());
43
44 has_pending_operation_ = true;
45 if (stream_impl_.get()) {
46 int result = InitiateWrite(buf, buf_len, callback);
47 if (result != net::ERR_IO_PENDING)
48 has_pending_operation_ = false;
49 return result;
50 }
51 return InitiateOpen(callback,
52 base::Bind(&LocalFileWriter::ReadyToWrite,
53 weak_factory_.GetWeakPtr(),
54 make_scoped_refptr(buf), buf_len, callback));
55 }
56
57 int LocalFileWriter::Cancel(const net::CompletionCallback& callback) {
58 if (!has_pending_operation_)
59 return net::ERR_UNEXPECTED;
60
61 DCHECK(!callback.is_null());
62 cancel_callback_ = callback;
63 return net::ERR_IO_PENDING;
64 }
65
66 int LocalFileWriter::InitiateOpen(const net::CompletionCallback& error_callback,
67 const base::Closure& main_operation) {
68 DCHECK(has_pending_operation_);
69 DCHECK(!stream_impl_.get());
70
71 stream_impl_.reset(new net::FileStream(NULL));
72 return stream_impl_->Open(file_path_,
73 kOpenFlagsForWrite,
74 base::Bind(&LocalFileWriter::DidOpen,
75 weak_factory_.GetWeakPtr(),
76 error_callback,
77 main_operation));
78 }
79
80 void LocalFileWriter::DidOpen(const net::CompletionCallback& error_callback,
81 const base::Closure& main_operation,
82 int result) {
83 DCHECK(has_pending_operation_);
84 DCHECK(stream_impl_.get());
85
86 if (CancelIfRequested())
87 return;
88
89 if (result != net::OK) {
90 has_pending_operation_ = false;
91 stream_impl_.reset(NULL);
92 error_callback.Run(result);
93 return;
94 }
95
96 InitiateSeek(error_callback, main_operation);
97 }
98
99 void LocalFileWriter::InitiateSeek(
100 const net::CompletionCallback& error_callback,
101 const base::Closure& main_operation) {
102 DCHECK(has_pending_operation_);
103 DCHECK(stream_impl_.get());
104
105 if (initial_offset_ == 0) {
106 // No need to seek.
107 main_operation.Run();
108 return;
109 }
110
111 int result = stream_impl_->Seek(net::FROM_BEGIN, initial_offset_,
112 base::Bind(&LocalFileWriter::DidSeek,
113 weak_factory_.GetWeakPtr(),
114 error_callback,
115 main_operation));
116 if (result != net::ERR_IO_PENDING) {
117 has_pending_operation_ = false;
118 error_callback.Run(result);
119 }
120 }
121
122 void LocalFileWriter::DidSeek(const net::CompletionCallback& error_callback,
123 const base::Closure& main_operation,
124 int64 result) {
125 DCHECK(has_pending_operation_);
126
127 if (CancelIfRequested())
128 return;
129
130 if (result != initial_offset_) {
131 // TODO(kinaba) add a more specific error code.
132 result = net::ERR_FAILED;
133 }
134
135 if (result < 0) {
136 has_pending_operation_ = false;
137 error_callback.Run(static_cast<int>(result));
138 return;
139 }
140
141 main_operation.Run();
142 }
143
144 void LocalFileWriter::ReadyToWrite(net::IOBuffer* buf, int buf_len,
145 const net::CompletionCallback& callback) {
146 DCHECK(has_pending_operation_);
147
148 int result = InitiateWrite(buf, buf_len, callback);
149 if (result != net::ERR_IO_PENDING) {
150 has_pending_operation_ = false;
151 callback.Run(result);
152 }
153 }
154
155 int LocalFileWriter::InitiateWrite(net::IOBuffer* buf, int buf_len,
156 const net::CompletionCallback& callback) {
157 DCHECK(has_pending_operation_);
158 DCHECK(stream_impl_.get());
159
160 return stream_impl_->Write(buf, buf_len,
161 base::Bind(&LocalFileWriter::DidWrite,
162 weak_factory_.GetWeakPtr(),
163 callback));
164 }
165
166 void LocalFileWriter::DidWrite(const net::CompletionCallback& callback,
167 int result) {
168 DCHECK(has_pending_operation_);
169
170 if (CancelIfRequested())
171 return;
172 has_pending_operation_ = false;
173 callback.Run(result);
174 }
175
176 bool LocalFileWriter::CancelIfRequested() {
177 DCHECK(has_pending_operation_);
178
179 if (cancel_callback_.is_null())
180 return false;
181
182 net::CompletionCallback pending_cancel = cancel_callback_;
183 has_pending_operation_ = false;
184 cancel_callback_.Reset();
185 pending_cancel.Run(net::OK);
186 return true;
187 }
188
189 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698