Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(261)

Side by Side Diff: android_webview/browser/input_stream_impl.cc

Issue 2889193004: [WebView] Replace AwContentsIoThreadClient, InputStream and AwWebResourceResponse (Closed)
Patch Set: fix test crash Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 "android_webview/browser/input_stream_impl.h"
6
7 #include "base/android/jni_android.h"
8 // Disable "Warnings treated as errors" for input_stream_jni as it's a Java
9 // system class and we have to generate C++ hooks for all methods in the class
10 // even if they're unused.
11 #pragma GCC diagnostic push
12 #pragma GCC diagnostic ignored "-Wunused-function"
13 #include "jni/InputStreamUtil_jni.h"
14 #pragma GCC diagnostic pop
15 #include "net/base/io_buffer.h"
16
17 using base::android::AttachCurrentThread;
18 using base::android::ClearException;
19 using base::android::JavaRef;
20
21 namespace android_webview {
22
23 namespace {
24
25 // This should be the same as InputStramUtil.EXCEPTION_THROWN_STATUS.
26 const int kExceptionThrownStatusCode = -2;
27 }
28
29 // Maximum number of bytes to be read in a single read.
30 const int InputStreamImpl::kBufferSize = 4096;
31
32 // static
33 const InputStreamImpl* InputStreamImpl::FromInputStream(
34 const InputStream* input_stream) {
35 return static_cast<const InputStreamImpl*>(input_stream);
36 }
37
38 // TODO: Use unsafe version for all Java_InputStream methods in this file
39 // once BUG 157880 is fixed and implement graceful exception handling.
40
41 InputStreamImpl::InputStreamImpl() {}
42
43 InputStreamImpl::InputStreamImpl(const JavaRef<jobject>& stream)
44 : jobject_(stream) {
45 DCHECK(!stream.is_null());
46 }
47
48 InputStreamImpl::~InputStreamImpl() {
49 JNIEnv* env = AttachCurrentThread();
50 Java_InputStreamUtil_close(env, jobject_);
51 }
52
53 bool InputStreamImpl::BytesAvailable(int* bytes_available) const {
54 JNIEnv* env = AttachCurrentThread();
55 int bytes = Java_InputStreamUtil_available(env, jobject_);
56 if (bytes == kExceptionThrownStatusCode)
57 return false;
58 *bytes_available = bytes;
59 return true;
60 }
61
62 bool InputStreamImpl::Skip(int64_t n, int64_t* bytes_skipped) {
63 JNIEnv* env = AttachCurrentThread();
64 int bytes = Java_InputStreamUtil_skip(env, jobject_, n);
65 if (bytes < 0)
66 return false;
67 if (bytes > n)
68 return false;
69 *bytes_skipped = bytes;
70 return true;
71 }
72
73 bool InputStreamImpl::Read(net::IOBuffer* dest, int length, int* bytes_read) {
74 JNIEnv* env = AttachCurrentThread();
75 if (!buffer_.obj()) {
76 // Allocate transfer buffer.
77 base::android::ScopedJavaLocalRef<jbyteArray> temp(
78 env, env->NewByteArray(kBufferSize));
79 buffer_.Reset(temp);
80 if (ClearException(env))
81 return false;
82 }
83
84 int remaining_length = length;
85 char* dest_write_ptr = dest->data();
86 *bytes_read = 0;
87
88 while (remaining_length > 0) {
89 const int max_transfer_length = std::min(remaining_length, kBufferSize);
90 const int transfer_length = Java_InputStreamUtil_read(
91 env, jobject_, buffer_, 0, max_transfer_length);
92 if (transfer_length == kExceptionThrownStatusCode)
93 return false;
94
95 if (transfer_length < 0) // EOF
96 break;
97
98 // Note: it is possible, yet unlikely, that the Java InputStream returns
99 // a transfer_length == 0 from time to time. In such cases we just continue
100 // the read until we get either valid data or reach EOF.
101 if (transfer_length == 0)
102 continue;
103
104 DCHECK_GE(max_transfer_length, transfer_length);
105 DCHECK_GE(env->GetArrayLength(buffer_.obj()), transfer_length);
106
107 // This check is to prevent a malicious InputStream implementation from
108 // overrunning the |dest| buffer.
109 if (transfer_length > max_transfer_length)
110 return false;
111
112 // Copy the data over to the provided C++ IOBuffer.
113 DCHECK_GE(remaining_length, transfer_length);
114 env->GetByteArrayRegion(buffer_.obj(), 0, transfer_length,
115 reinterpret_cast<jbyte*>(dest_write_ptr));
116 if (ClearException(env))
117 return false;
118
119 remaining_length -= transfer_length;
120 dest_write_ptr += transfer_length;
121 }
122 // bytes_read can be strictly less than the req. length if EOF is encountered.
123 DCHECK_GE(remaining_length, 0);
124 DCHECK_LE(remaining_length, length);
125 *bytes_read = length - remaining_length;
126 return true;
127 }
128
129 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698