Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / webkit / browser / fileapi / file_system_file_stream_reader.cc
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/browser/fileapi/file_system_file_stream_reader.h"
6
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"
16
17 using webkit_blob::FileStreamReader;
18
19 // TODO(kinuko): Remove this temporary namespace hack after we move both
20 // blob and fileapi into content namespace.
21 namespace webkit_blob {
22
23 FileStreamReader* FileStreamReader::CreateForFileSystemFile(
24     fileapi::FileSystemContext* file_system_context,
25     const fileapi::FileSystemURL& url,
26     int64 initial_offset,
27     const base::Time& expected_modification_time) {
28   return new fileapi::FileSystemFileStreamReader(
29       file_system_context,
30       url,
31       initial_offset,
32       expected_modification_time);
33 }
34
35 }  // namespace webkit_blob
36
37 namespace fileapi {
38
39 namespace {
40
41 void ReadAdapter(base::WeakPtr<FileSystemFileStreamReader> reader,
42                  net::IOBuffer* buf, int buf_len,
43                  const net::CompletionCallback& callback) {
44   if (!reader.get())
45     return;
46   int rv = reader->Read(buf, buf_len, callback);
47   if (rv != net::ERR_IO_PENDING)
48     callback.Run(rv);
49 }
50
51 void GetLengthAdapter(base::WeakPtr<FileSystemFileStreamReader> reader,
52                       const net::Int64CompletionCallback& callback) {
53   if (!reader.get())
54     return;
55   int rv = reader->GetLength(callback);
56   if (rv != net::ERR_IO_PENDING)
57     callback.Run(rv);
58 }
59
60 void Int64CallbackAdapter(const net::Int64CompletionCallback& callback,
61                           int value) {
62   callback.Run(value);
63 }
64
65 }  // namespace
66
67 FileSystemFileStreamReader::~FileSystemFileStreamReader() {
68 }
69
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),
78       callback);
79 }
80
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));
88 }
89
90 FileSystemFileStreamReader::FileSystemFileStreamReader(
91     FileSystemContext* file_system_context,
92     const FileSystemURL& url,
93     int64 initial_offset,
94     const base::Time& expected_modification_time)
95     : file_system_context_(file_system_context),
96       url_(url),
97       initial_offset_(initial_offset),
98       expected_modification_time_(expected_modification_time),
99       has_pending_create_snapshot_(false),
100       weak_factory_(this) {
101 }
102
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(
109       url_,
110       base::Bind(&FileSystemFileStreamReader::DidCreateSnapshot,
111                  weak_factory_.GetWeakPtr(),
112                  callback,
113                  error_callback));
114   return net::ERR_IO_PENDING;
115 }
116
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;
127
128   if (file_error != base::File::FILE_OK) {
129     error_callback.Run(net::FileErrorToNetError(file_error));
130     return;
131   }
132
133   // Keep the reference (if it's non-null) so that the file won't go away.
134   snapshot_ref_ = file_ref;
135
136   local_file_reader_.reset(
137       FileStreamReader::CreateForLocalFile(
138           file_system_context_->default_file_task_runner(),
139           platform_path, initial_offset_, expected_modification_time_));
140
141   callback.Run();
142 }
143
144 }  // namespace fileapi