Index: webkit/browser/blob/content_url_stream_reader_android.cc |
diff --git a/webkit/browser/blob/content_url_stream_reader_android.cc b/webkit/browser/blob/content_url_stream_reader_android.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7566dca287aefbbee4e586e704ddc81a3d4c603e |
--- /dev/null |
+++ b/webkit/browser/blob/content_url_stream_reader_android.cc |
@@ -0,0 +1,114 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "webkit/browser/blob/content_url_stream_reader_android.h" |
+ |
+#include "base/file_util.h" |
+#include "base/files/file_util_proxy.h" |
+#include "base/location.h" |
+#include "base/logging.h" |
+#include "base/platform_file.h" |
+#include "base/task_runner.h" |
+#include "net/android/content_uri_utils.h" |
+#include "net/base/file_stream.h" |
+#include "net/base/io_buffer.h" |
+#include "net/base/net_errors.h" |
+ |
+namespace webkit_blob { |
+ |
+const int kOpenFlagsForRead = base::PLATFORM_FILE_OPEN | |
+ base::PLATFORM_FILE_READ | |
+ base::PLATFORM_FILE_ASYNC; |
+ |
+FileStreamReader* FileStreamReader::CreateForContentUrl( |
+ base::TaskRunner* task_runner, |
+ const GURL& content_url, |
+ int64 initial_offset) { |
+ return new ContentUrlStreamReader(task_runner, content_url, initial_offset); |
+} |
+ |
+ContentUrlStreamReader::ContentUrlStreamReader( |
+ base::TaskRunner* task_runner, |
+ const GURL& content_url, |
+ int64 initial_offset) |
+ : task_runner_(task_runner), |
+ content_url_(content_url), |
+ initial_offset_(initial_offset), |
+ weak_factory_(this) {} |
+ |
+ContentUrlStreamReader::~ContentUrlStreamReader() {} |
+ |
+int64 ContentUrlStreamReader::GetLength( |
+ const net::Int64CompletionCallback& callback) { |
+ net::GetContentUrlLength(task_runner_.get(), content_url_, callback); |
+ return net::ERR_IO_PENDING; |
+} |
+ |
+int ContentUrlStreamReader::Read(net::IOBuffer* buf, int buf_len, |
+ const net::CompletionCallback& callback) { |
+ if (stream_impl_) |
+ return stream_impl_->Read(buf, buf_len, callback); |
+ return Open(base::Bind(&ContentUrlStreamReader::DidOpenForRead, |
+ weak_factory_.GetWeakPtr(), |
+ make_scoped_refptr(buf), buf_len, callback)); |
+} |
+ |
+int ContentUrlStreamReader::Open(const net::CompletionCallback& callback) { |
+ DCHECK(!stream_impl_); |
+ stream_impl_.reset(new net::FileStream(NULL, task_runner_)); |
+ const int result = stream_impl_->OpenContentUrl( |
+ content_url_, kOpenFlagsForRead, |
+ base::Bind(&ContentUrlStreamReader::DidOpenContentUrl, |
+ weak_factory_.GetWeakPtr(), |
+ callback)); |
+ return result; |
+} |
+ |
+void ContentUrlStreamReader::DidOpenContentUrl( |
+ const net::CompletionCallback& callback, |
+ int result) { |
+ if (result != net::OK) { |
+ callback.Run(result); |
+ return; |
+ } |
+ |
+ result = stream_impl_->Seek( |
+ net::FROM_BEGIN, initial_offset_, |
+ base::Bind(&ContentUrlStreamReader::DidSeekContentUrl, |
+ weak_factory_.GetWeakPtr(), |
+ callback)); |
+ if (result != net::ERR_IO_PENDING) |
+ callback.Run(result); |
+} |
+ |
+void ContentUrlStreamReader::DidOpenForRead( |
+ net::IOBuffer* buf, |
+ int buf_len, |
+ const net::CompletionCallback& callback, |
+ int open_result) { |
+ if (open_result != net::OK) { |
+ stream_impl_.reset(); |
+ callback.Run(open_result); |
+ return; |
+ } |
+ const int read_result = stream_impl_->Read(buf, buf_len, callback); |
+ if (read_result != net::ERR_IO_PENDING) |
+ callback.Run(read_result); |
+} |
+ |
+void ContentUrlStreamReader::DidSeekContentUrl( |
+ const net::CompletionCallback& callback, |
+ int64 seek_result) { |
+ if (seek_result < 0) { |
+ callback.Run(static_cast<int>(seek_result)); |
+ return; |
+ } |
+ if (seek_result != initial_offset_) { |
+ callback.Run(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE); |
+ return; |
+ } |
+ callback.Run(net::OK); |
+} |
+ |
+} // namespace webkit_blob |