• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "storage/browser/fileapi/file_system_file_stream_reader.h"
6 
7 #include "base/files/file_util_proxy.h"
8 #include "base/single_thread_task_runner.h"
9 #include "net/base/file_stream.h"
10 #include "net/base/io_buffer.h"
11 #include "net/base/net_errors.h"
12 #include "storage/browser/blob/file_stream_reader.h"
13 #include "storage/browser/fileapi/file_system_context.h"
14 #include "storage/browser/fileapi/file_system_operation_runner.h"
15 
16 using storage::FileStreamReader;
17 
18 // TODO(kinuko): Remove this temporary namespace hack after we move both
19 // blob and fileapi into content namespace.
20 namespace storage {
21 
CreateForFileSystemFile(storage::FileSystemContext * file_system_context,const storage::FileSystemURL & url,int64 initial_offset,const base::Time & expected_modification_time)22 FileStreamReader* FileStreamReader::CreateForFileSystemFile(
23     storage::FileSystemContext* file_system_context,
24     const storage::FileSystemURL& url,
25     int64 initial_offset,
26     const base::Time& expected_modification_time) {
27   return new storage::FileSystemFileStreamReader(
28       file_system_context, url, initial_offset, expected_modification_time);
29 }
30 
31 }  // namespace storage
32 
33 namespace storage {
34 
35 namespace {
36 
ReadAdapter(base::WeakPtr<FileSystemFileStreamReader> reader,net::IOBuffer * buf,int buf_len,const net::CompletionCallback & callback)37 void ReadAdapter(base::WeakPtr<FileSystemFileStreamReader> reader,
38                  net::IOBuffer* buf, int buf_len,
39                  const net::CompletionCallback& callback) {
40   if (!reader.get())
41     return;
42   int rv = reader->Read(buf, buf_len, callback);
43   if (rv != net::ERR_IO_PENDING)
44     callback.Run(rv);
45 }
46 
GetLengthAdapter(base::WeakPtr<FileSystemFileStreamReader> reader,const net::Int64CompletionCallback & callback)47 void GetLengthAdapter(base::WeakPtr<FileSystemFileStreamReader> reader,
48                       const net::Int64CompletionCallback& callback) {
49   if (!reader.get())
50     return;
51   int rv = reader->GetLength(callback);
52   if (rv != net::ERR_IO_PENDING)
53     callback.Run(rv);
54 }
55 
Int64CallbackAdapter(const net::Int64CompletionCallback & callback,int value)56 void Int64CallbackAdapter(const net::Int64CompletionCallback& callback,
57                           int value) {
58   callback.Run(value);
59 }
60 
61 }  // namespace
62 
~FileSystemFileStreamReader()63 FileSystemFileStreamReader::~FileSystemFileStreamReader() {
64 }
65 
Read(net::IOBuffer * buf,int buf_len,const net::CompletionCallback & callback)66 int FileSystemFileStreamReader::Read(
67     net::IOBuffer* buf, int buf_len,
68     const net::CompletionCallback& callback) {
69   if (local_file_reader_)
70     return local_file_reader_->Read(buf, buf_len, callback);
71   return CreateSnapshot(
72       base::Bind(&ReadAdapter, weak_factory_.GetWeakPtr(),
73                  make_scoped_refptr(buf), buf_len, callback),
74       callback);
75 }
76 
GetLength(const net::Int64CompletionCallback & callback)77 int64 FileSystemFileStreamReader::GetLength(
78     const net::Int64CompletionCallback& callback) {
79   if (local_file_reader_)
80     return local_file_reader_->GetLength(callback);
81   return CreateSnapshot(
82       base::Bind(&GetLengthAdapter, weak_factory_.GetWeakPtr(), callback),
83       base::Bind(&Int64CallbackAdapter, callback));
84 }
85 
FileSystemFileStreamReader(FileSystemContext * file_system_context,const FileSystemURL & url,int64 initial_offset,const base::Time & expected_modification_time)86 FileSystemFileStreamReader::FileSystemFileStreamReader(
87     FileSystemContext* file_system_context,
88     const FileSystemURL& url,
89     int64 initial_offset,
90     const base::Time& expected_modification_time)
91     : file_system_context_(file_system_context),
92       url_(url),
93       initial_offset_(initial_offset),
94       expected_modification_time_(expected_modification_time),
95       has_pending_create_snapshot_(false),
96       weak_factory_(this) {
97 }
98 
CreateSnapshot(const base::Closure & callback,const net::CompletionCallback & error_callback)99 int FileSystemFileStreamReader::CreateSnapshot(
100     const base::Closure& callback,
101     const net::CompletionCallback& error_callback) {
102   DCHECK(!has_pending_create_snapshot_);
103   has_pending_create_snapshot_ = true;
104   file_system_context_->operation_runner()->CreateSnapshotFile(
105       url_,
106       base::Bind(&FileSystemFileStreamReader::DidCreateSnapshot,
107                  weak_factory_.GetWeakPtr(),
108                  callback,
109                  error_callback));
110   return net::ERR_IO_PENDING;
111 }
112 
DidCreateSnapshot(const base::Closure & callback,const net::CompletionCallback & error_callback,base::File::Error file_error,const base::File::Info & file_info,const base::FilePath & platform_path,const scoped_refptr<storage::ShareableFileReference> & file_ref)113 void FileSystemFileStreamReader::DidCreateSnapshot(
114     const base::Closure& callback,
115     const net::CompletionCallback& error_callback,
116     base::File::Error file_error,
117     const base::File::Info& file_info,
118     const base::FilePath& platform_path,
119     const scoped_refptr<storage::ShareableFileReference>& file_ref) {
120   DCHECK(has_pending_create_snapshot_);
121   DCHECK(!local_file_reader_.get());
122   has_pending_create_snapshot_ = false;
123 
124   if (file_error != base::File::FILE_OK) {
125     error_callback.Run(net::FileErrorToNetError(file_error));
126     return;
127   }
128 
129   // Keep the reference (if it's non-null) so that the file won't go away.
130   snapshot_ref_ = file_ref;
131 
132   local_file_reader_.reset(
133       FileStreamReader::CreateForLocalFile(
134           file_system_context_->default_file_task_runner(),
135           platform_path, initial_offset_, expected_modification_time_));
136 
137   callback.Run();
138 }
139 
140 }  // namespace storage
141