Index: android_webview/native/input_stream_reader.cc |
diff --git a/android_webview/native/input_stream_reader.cc b/android_webview/native/input_stream_reader.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9b5befb1f728640d0424d034d9dbe5d7359ee30a |
--- /dev/null |
+++ b/android_webview/native/input_stream_reader.cc |
@@ -0,0 +1,123 @@ |
+// Copyright (c) 2012 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 "android_webview/native/input_stream_reader.h" |
+ |
+#include "android_webview/native/input_stream.h" |
+#include "base/message_loop.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "net/base/net_errors.h" |
+#include "net/http/http_byte_range.h" |
+ |
joth
2012/11/07 16:55:38
ISTM this class is now fairly well abstracted from
mkosiba (inactive)
2012/11/15 19:18:50
Done.
|
+using base::android::AttachCurrentThread; |
+using content::BrowserThread; |
+ |
+namespace android_webview { |
+ |
+InputStreamReader::InputStreamReader( |
+ android_webview::InputStream* stream) |
+ : stream_(stream) { |
+ DCHECK(stream); |
+} |
+ |
+InputStreamReader::~InputStreamReader() { |
+} |
+ |
+void InputStreamReader::Seek(net::HttpByteRange byte_range, |
+ net::CompletionCallback on_seek_completion) { |
+ JNIEnv* env = AttachCurrentThread(); |
+ int content_size = 0; |
+ DCHECK(env); |
+ |
+ int error_code = VerifyRequestedRange(env, &byte_range, &content_size); |
+ if (error_code != net::OK) { |
+ PostCompletionCallback(on_seek_completion, error_code); |
+ return; |
+ } |
+ |
+ error_code = SkipToRequestedRange(env, byte_range); |
+ if (error_code != net::OK) { |
+ PostCompletionCallback(on_seek_completion, error_code); |
+ return; |
+ } |
+ |
+ DCHECK_GE(content_size, 0); |
+ PostCompletionCallback(on_seek_completion, content_size); |
+} |
+ |
+void InputStreamReader::ReadRawData( |
+ net::IOBuffer* dest, |
+ int dest_size, |
+ net::CompletionCallback on_read_completion) { |
+ if (!dest_size) { |
+ PostCompletionCallback(on_read_completion, 0); |
+ return; |
+ } |
+ |
+ JNIEnv* env = AttachCurrentThread(); |
+ DCHECK(env); |
+ DCHECK_GT(dest_size, 0); |
+ |
+ int bytes_read = 0; |
+ if (!stream_->Read(env, dest, dest_size, &bytes_read)) |
+ PostCompletionCallback(on_read_completion, net::ERR_FAILED); |
+ else |
+ PostCompletionCallback(on_read_completion, bytes_read); |
+} |
+ |
+int InputStreamReader::VerifyRequestedRange( |
+ JNIEnv* env, |
+ net::HttpByteRange* byte_range, |
+ int* content_size) { |
+ DCHECK(content_size); |
+ int32_t size = 0; |
+ if (!stream_->BytesAvailable(env, &size)) { |
+ return net::ERR_FAILED; |
+ } |
+ |
+ if (size <= 0) |
+ return net::OK; |
+ |
+ // Check that the requested range was valid. |
+ if (!byte_range->ComputeBounds(size)) { |
+ return net::ERR_REQUEST_RANGE_NOT_SATISFIABLE; |
+ } |
+ |
+ size = byte_range->last_byte_position() - |
+ byte_range->first_byte_position() + 1; |
+ DCHECK_GE(size, 0); |
+ *content_size = size; |
+ |
+ return net::OK; |
+} |
+ |
+int InputStreamReader::SkipToRequestedRange( |
+ JNIEnv* env, |
+ const net::HttpByteRange& byte_range) { |
+ // Skip to the start of the requested data. This has to be done in a loop |
+ // because the underlying InputStream is not guaranteed to skip the requested |
+ // number of bytes. |
+ if (byte_range.IsValid() && byte_range.first_byte_position() != 0) { |
+ int64_t skipped, bytes_to_skip = byte_range.first_byte_position(); |
+ do { |
+ if (!stream_->Skip(env, bytes_to_skip, &skipped)) { |
+ return net::ERR_FAILED; |
+ } |
+ if (skipped <= 0) { |
+ return net::ERR_REQUEST_RANGE_NOT_SATISFIABLE; |
+ } |
+ } while ((bytes_to_skip -= skipped) > 0); |
+ } |
+ return net::OK; |
+} |
+ |
+void InputStreamReader::PostCompletionCallback( |
+ const net::CompletionCallback& callback, |
+ int result) { |
+ BrowserThread::PostTask(BrowserThread::IO, |
joth
2012/11/07 16:55:38
this class is a little bit shady, that you can cal
benm (inactive)
2012/11/15 17:39:01
Agree, it'd be nice if you're always called back o
mkosiba (inactive)
2012/11/15 19:18:50
Done.
|
+ FROM_HERE, |
+ base::Bind(callback, result)); |
+} |
+ |
+} // namespace android_webview |