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 "webkit/chromeos/fileapi/remote_file_stream_writer.h"
7 #include "net/base/io_buffer.h"
8 #include "net/base/net_errors.h"
9 #include "webkit/blob/local_file_stream_reader.h"
10 #include "webkit/blob/shareable_file_reference.h"
11 #include "webkit/fileapi/local_file_stream_writer.h"
12 #include "webkit/fileapi/remote_file_system_proxy.h"
16 RemoteFileStreamWriter::RemoteFileStreamWriter(
17 const scoped_refptr
<RemoteFileSystemProxyInterface
>& remote_filesystem
,
18 const FileSystemURL
& url
,
20 : remote_filesystem_(remote_filesystem
),
22 initial_offset_(offset
),
23 has_pending_create_snapshot_(false),
24 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
27 RemoteFileStreamWriter::~RemoteFileStreamWriter() {
30 int RemoteFileStreamWriter::Write(net::IOBuffer
* buf
,
32 const net::CompletionCallback
& callback
) {
33 DCHECK(!has_pending_create_snapshot_
);
34 DCHECK(pending_cancel_callback_
.is_null());
36 if (!local_file_writer_
.get()) {
37 has_pending_create_snapshot_
= true;
38 // In this RemoteFileStreamWriter, we only create snapshot file and don't
39 // have explicit close operation. This is ok, because close is automatically
40 // triggered by a refcounted |file_ref_| passed to OnFileOpened, from the
41 // destructor of RemoteFileStreamWriter.
42 remote_filesystem_
->CreateWritableSnapshotFile(
44 base::Bind(&RemoteFileStreamWriter::OnFileOpened
,
45 weak_factory_
.GetWeakPtr(),
46 make_scoped_refptr(buf
),
49 return net::ERR_IO_PENDING
;
51 return local_file_writer_
->Write(buf
, buf_len
, callback
);
54 void RemoteFileStreamWriter::OnFileOpened(
57 const net::CompletionCallback
& callback
,
58 base::PlatformFileError open_result
,
59 const base::FilePath
& local_path
,
60 const scoped_refptr
<webkit_blob::ShareableFileReference
>& file_ref
) {
61 has_pending_create_snapshot_
= false;
62 if (!pending_cancel_callback_
.is_null()) {
63 InvokePendingCancelCallback(net::OK
);
67 if (open_result
!= base::PLATFORM_FILE_OK
) {
68 callback
.Run(net::PlatformFileErrorToNetError(open_result
));
72 // Hold the reference to the file. Releasing the reference notifies the file
73 // system about to close file.
76 DCHECK(!local_file_writer_
.get());
77 local_file_writer_
.reset(new fileapi::LocalFileStreamWriter(local_path
,
79 int result
= local_file_writer_
->Write(buf
, buf_len
, callback
);
80 if (result
!= net::ERR_IO_PENDING
)
84 int RemoteFileStreamWriter::Cancel(const net::CompletionCallback
& callback
) {
85 DCHECK(!callback
.is_null());
86 DCHECK(pending_cancel_callback_
.is_null());
88 // If file open operation is in-flight, wait for its completion and cancel
89 // further write operation in OnFileOpened.
90 if (has_pending_create_snapshot_
) {
91 pending_cancel_callback_
= callback
;
92 return net::ERR_IO_PENDING
;
95 // If LocalFileWriter is already created, just delegate the cancel to it.
96 if (local_file_writer_
.get()) {
97 pending_cancel_callback_
= callback
;
98 return local_file_writer_
->Cancel(
99 base::Bind(&RemoteFileStreamWriter::InvokePendingCancelCallback
,
100 weak_factory_
.GetWeakPtr()));
103 // Write() is not called yet.
104 return net::ERR_UNEXPECTED
;
107 int RemoteFileStreamWriter::Flush(const net::CompletionCallback
& callback
) {
108 // For remote file writer, Flush() is a no-op. Synchronization to the remote
109 // server is not done until the file is closed.
113 void RemoteFileStreamWriter::InvokePendingCancelCallback(int result
) {
114 net::CompletionCallback callback
= pending_cancel_callback_
;
115 pending_cancel_callback_
.Reset();
116 callback
.Run(result
);