1 // Copyright 2014 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 "chrome/browser/chromeos/drive/fileapi/webkit_file_stream_reader_impl.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/logging.h"
11 #include "chrome/browser/chromeos/drive/drive.pb.h"
12 #include "chrome/browser/chromeos/drive/drive_file_stream_reader.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "net/base/io_buffer.h"
15 #include "net/base/net_errors.h"
16 #include "net/http/http_byte_range.h"
18 using content::BrowserThread
;
23 WebkitFileStreamReaderImpl::WebkitFileStreamReaderImpl(
24 const DriveFileStreamReader::FileSystemGetter
& file_system_getter
,
25 base::SequencedTaskRunner
* file_task_runner
,
26 const base::FilePath
& drive_file_path
,
28 const base::Time
& expected_modification_time
)
30 new DriveFileStreamReader(file_system_getter
, file_task_runner
)),
31 drive_file_path_(drive_file_path
),
33 expected_modification_time_(expected_modification_time
),
35 weak_ptr_factory_(this) {
39 WebkitFileStreamReaderImpl::~WebkitFileStreamReaderImpl() {
42 int WebkitFileStreamReaderImpl::Read(net::IOBuffer
* buffer
,
44 const net::CompletionCallback
& callback
) {
45 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
46 DCHECK(stream_reader_
);
48 DCHECK(!callback
.is_null());
50 if (stream_reader_
->IsInitialized())
51 return stream_reader_
->Read(buffer
, buffer_length
, callback
);
53 net::HttpByteRange byte_range
;
54 byte_range
.set_first_byte_position(offset_
);
55 stream_reader_
->Initialize(
58 base::Bind(&WebkitFileStreamReaderImpl::OnStreamReaderInitialized
,
59 weak_ptr_factory_
.GetWeakPtr(),
60 base::Bind(&WebkitFileStreamReaderImpl
61 ::ReadAfterStreamReaderInitialized
,
62 weak_ptr_factory_
.GetWeakPtr(),
63 make_scoped_refptr(buffer
),
64 buffer_length
, callback
)));
65 return net::ERR_IO_PENDING
;
68 int64
WebkitFileStreamReaderImpl::GetLength(
69 const net::Int64CompletionCallback
& callback
) {
70 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
71 DCHECK(stream_reader_
);
72 DCHECK(!callback
.is_null());
74 if (stream_reader_
->IsInitialized()) {
75 // Returns file_size regardless of |offset_|.
79 net::HttpByteRange byte_range
;
80 byte_range
.set_first_byte_position(offset_
);
81 stream_reader_
->Initialize(
84 base::Bind(&WebkitFileStreamReaderImpl::OnStreamReaderInitialized
,
85 weak_ptr_factory_
.GetWeakPtr(),
86 base::Bind(&WebkitFileStreamReaderImpl
87 ::GetLengthAfterStreamReaderInitialized
,
88 weak_ptr_factory_
.GetWeakPtr(),
90 return net::ERR_IO_PENDING
;
93 void WebkitFileStreamReaderImpl::OnStreamReaderInitialized(
94 const net::CompletionCallback
& callback
,
96 scoped_ptr
<ResourceEntry
> entry
) {
97 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
98 DCHECK(stream_reader_
);
99 DCHECK(!callback
.is_null());
101 // TODO(hashimoto): Report ERR_UPLOAD_FILE_CHANGED when modification time
102 // doesn't match. crbug.com/346625
103 if (error
!= net::OK
) {
104 // Found an error. Close the |stream_reader_| and notify it to the caller.
105 stream_reader_
.reset();
110 // Remember the size of the file.
111 file_size_
= entry
->file_info().size();
112 callback
.Run(net::OK
);
115 void WebkitFileStreamReaderImpl::ReadAfterStreamReaderInitialized(
116 scoped_refptr
<net::IOBuffer
> buffer
,
118 const net::CompletionCallback
& callback
,
119 int initialization_result
) {
120 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
121 DCHECK(!callback
.is_null());
123 if (initialization_result
!= net::OK
) {
124 callback
.Run(initialization_result
);
128 DCHECK(stream_reader_
);
129 int result
= stream_reader_
->Read(buffer
.get(), buffer_length
, callback
);
130 if (result
!= net::ERR_IO_PENDING
)
131 callback
.Run(result
);
134 void WebkitFileStreamReaderImpl::GetLengthAfterStreamReaderInitialized(
135 const net::Int64CompletionCallback
& callback
,
136 int initialization_result
) {
137 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
138 DCHECK(!callback
.is_null());
140 if (initialization_result
!= net::OK
) {
141 callback
.Run(initialization_result
);
145 DCHECK_GE(file_size_
, 0);
146 callback
.Run(file_size_
);
149 } // namespace internal