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/browser/fileapi/file_system_file_stream_reader.h"
7 #include "base/files/file_util_proxy.h"
8 #include "base/platform_file.h"
9 #include "base/single_thread_task_runner.h"
10 #include "net/base/file_stream.h"
11 #include "net/base/io_buffer.h"
12 #include "net/base/net_errors.h"
13 #include "webkit/browser/blob/file_stream_reader.h"
14 #include "webkit/browser/fileapi/file_system_context.h"
15 #include "webkit/browser/fileapi/file_system_operation_runner.h"
17 using webkit_blob::FileStreamReader;
19 // TODO(kinuko): Remove this temporary namespace hack after we move both
20 // blob and fileapi into content namespace.
21 namespace webkit_blob {
23 FileStreamReader* FileStreamReader::CreateForFileSystemFile(
24 fileapi::FileSystemContext* file_system_context,
25 const fileapi::FileSystemURL& url,
27 const base::Time& expected_modification_time) {
28 return new fileapi::FileSystemFileStreamReader(
32 expected_modification_time);
35 } // namespace webkit_blob
41 void ReadAdapter(base::WeakPtr<FileSystemFileStreamReader> reader,
42 net::IOBuffer* buf, int buf_len,
43 const net::CompletionCallback& callback) {
46 int rv = reader->Read(buf, buf_len, callback);
47 if (rv != net::ERR_IO_PENDING)
51 void GetLengthAdapter(base::WeakPtr<FileSystemFileStreamReader> reader,
52 const net::Int64CompletionCallback& callback) {
55 int rv = reader->GetLength(callback);
56 if (rv != net::ERR_IO_PENDING)
60 void Int64CallbackAdapter(const net::Int64CompletionCallback& callback,
67 FileSystemFileStreamReader::~FileSystemFileStreamReader() {
70 int FileSystemFileStreamReader::Read(
71 net::IOBuffer* buf, int buf_len,
72 const net::CompletionCallback& callback) {
73 if (local_file_reader_)
74 return local_file_reader_->Read(buf, buf_len, callback);
75 return CreateSnapshot(
76 base::Bind(&ReadAdapter, weak_factory_.GetWeakPtr(),
77 make_scoped_refptr(buf), buf_len, callback),
81 int64 FileSystemFileStreamReader::GetLength(
82 const net::Int64CompletionCallback& callback) {
83 if (local_file_reader_)
84 return local_file_reader_->GetLength(callback);
85 return CreateSnapshot(
86 base::Bind(&GetLengthAdapter, weak_factory_.GetWeakPtr(), callback),
87 base::Bind(&Int64CallbackAdapter, callback));
90 FileSystemFileStreamReader::FileSystemFileStreamReader(
91 FileSystemContext* file_system_context,
92 const FileSystemURL& url,
94 const base::Time& expected_modification_time)
95 : file_system_context_(file_system_context),
97 initial_offset_(initial_offset),
98 expected_modification_time_(expected_modification_time),
99 has_pending_create_snapshot_(false),
100 weak_factory_(this) {
103 int FileSystemFileStreamReader::CreateSnapshot(
104 const base::Closure& callback,
105 const net::CompletionCallback& error_callback) {
106 DCHECK(!has_pending_create_snapshot_);
107 has_pending_create_snapshot_ = true;
108 file_system_context_->operation_runner()->CreateSnapshotFile(
110 base::Bind(&FileSystemFileStreamReader::DidCreateSnapshot,
111 weak_factory_.GetWeakPtr(),
114 return net::ERR_IO_PENDING;
117 void FileSystemFileStreamReader::DidCreateSnapshot(
118 const base::Closure& callback,
119 const net::CompletionCallback& error_callback,
120 base::File::Error file_error,
121 const base::File::Info& file_info,
122 const base::FilePath& platform_path,
123 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
124 DCHECK(has_pending_create_snapshot_);
125 DCHECK(!local_file_reader_.get());
126 has_pending_create_snapshot_ = false;
128 if (file_error != base::File::FILE_OK) {
129 error_callback.Run(net::FileErrorToNetError(file_error));
133 // Keep the reference (if it's non-null) so that the file won't go away.
134 snapshot_ref_ = file_ref;
136 local_file_reader_.reset(
137 FileStreamReader::CreateForLocalFile(
138 file_system_context_->default_file_task_runner(),
139 platform_path, initial_offset_, expected_modification_time_));
144 } // namespace fileapi