Chromium Code Reviews| Index: android_webview/native/input_stream_impl.cc |
| diff --git a/android_webview/native/input_stream_impl.cc b/android_webview/native/input_stream_impl.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..6edfa931b10744f96f93ad13802af25532056c4b |
| --- /dev/null |
| +++ b/android_webview/native/input_stream_impl.cc |
| @@ -0,0 +1,115 @@ |
| +// 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_impl.h" |
| + |
| +#include "base/android/jni_android.h" |
| +#include "net/base/io_buffer.h" |
| +// Disable "Warnings treated as errors" for input_stream_jni as it's a Java |
| +// system class and we have to generate C++ hooks for all methods in the class |
| +// even if they're unused. |
| +#pragma GCC diagnostic ignored "-Wunused-function" |
| +#include "jni/InputStream_jni.h" |
| + |
| +using base::android::AttachCurrentThread; |
| +using base::android::ClearException; |
| +using base::android::JavaRef; |
| +using JNI_InputStream::Java_InputStream_available; |
| +using JNI_InputStream::Java_InputStream_skip; |
| +using JNI_InputStream::Java_InputStream_readI_AB_I_I; |
| + |
| +namespace android_webview { |
| + |
| +bool RegisterInputStream(JNIEnv* env) { |
| + return JNI_InputStream::RegisterNativesImpl(env); |
| +} |
| + |
| +// Maximum number of bytes to be read in a single read. |
| +const int InputStreamImpl::kBufferSize = 4096; |
| + |
| +//static |
| +const InputStreamImpl* InputStreamImpl::FromInputStream( |
| + const InputStream* input_stream) { |
| + return static_cast<const InputStreamImpl*>(input_stream); |
| +} |
| + |
| +InputStreamImpl::InputStreamImpl() { |
| +} |
| + |
| +InputStreamImpl::InputStreamImpl(const JavaRef<jobject>& stream) |
| + : jobject_(stream) { |
| + DCHECK(!stream.is_null()); |
| +} |
| + |
| +InputStreamImpl::~InputStreamImpl() { |
| +} |
| + |
| +bool InputStreamImpl::BytesAvailable(int* bytes_available) const { |
| + JNIEnv* env = AttachCurrentThread(); |
| + DCHECK(env); |
|
joth
2012/11/20 20:46:35
nit: never need DCHECK(env), AttachCurrentThread d
mkosiba (inactive)
2012/11/21 15:19:47
Done.
|
| + // TODO: Use unsafe version once BUG 157880 is fixed. |
|
joth
2012/11/20 20:46:35
nit: bug 160011 seems specific to this file? (mult
mkosiba (inactive)
2012/11/21 15:19:47
fixing 160011 would currently affect only this fil
|
| + int bytes = Java_InputStream_available(env, jobject_.obj()); |
| + if (ClearException(env)) |
| + return false; |
| + *bytes_available = bytes; |
| + return true; |
| +} |
| + |
| +bool InputStreamImpl::Skip(int64_t n, int64_t* bytes_skipped) { |
| + JNIEnv* env = AttachCurrentThread(); |
| + DCHECK(env); |
| + // TODO: Use unsafe version once BUG 157880 is fixed. |
| + int bytes = Java_InputStream_skip(env, jobject_.obj(), n); |
| + if (ClearException(env)) |
| + return false; |
| + *bytes_skipped = bytes; |
| + return true; |
| +} |
| + |
| +bool InputStreamImpl::Read(net::IOBuffer* dest, int length, int* bytes_read) { |
| + JNIEnv* env = AttachCurrentThread(); |
| + DCHECK(env); |
| + // TODO: Use unsafe version once BUG 157880 is fixed. |
|
joth
2012/11/20 20:46:35
don't think you mean TODO here? line 87.
mkosiba (inactive)
2012/11/21 15:19:47
Done.
|
| + if (!buffer_.obj()) { |
| + // Allocate transfer buffer. |
| + buffer_.Reset(env, env->NewByteArray(kBufferSize)); |
| + if (ClearException(env)) |
| + return false; |
| + } |
| + |
| + jbyteArray buffer = buffer_.obj(); |
| + int read_size = std::min(length, kBufferSize); |
|
joth
2012/11/20 20:46:35
move this inside the loop, else it will over-read
mkosiba (inactive)
2012/11/21 15:19:47
right, good spot.
|
| + *bytes_read = 0; |
| + |
| + while (length > 0) { |
| + int32_t byte_count = |
| + Java_InputStream_readI_AB_I_I( |
| + env, jobject_.obj(), buffer, 0, read_size); |
| + |
| + if (ClearException(env)) |
| + return false; |
| + |
| + if (byte_count <= 0) |
| + break; |
| + |
| +#ifndef NDEBUG |
| + int32_t buffer_length = env->GetArrayLength(buffer); |
| + DCHECK_GE(read_size, byte_count); |
| + DCHECK_GE(buffer_length, byte_count); |
| +#endif // NDEBUG |
| + |
| + // Copy the data over to the provided C++ side buffer. |
| + DCHECK_GE(length, byte_count); |
| + env->GetByteArrayRegion(buffer, 0, byte_count, |
| + reinterpret_cast<jbyte*>(dest->data() + *bytes_read)); |
| + if (ClearException(env)) |
| + return false; |
| + |
| + *bytes_read += byte_count; |
| + length -= byte_count; |
| + } |
| + return true; |
| +} |
| + |
| +} // namespace android_webview |