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

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

Issue 2863233002: [WebView] Move files from native to browser (Closed)
Patch Set: 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/native/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
30 // Maximum number of bytes to be read in a single read.
31 const int InputStreamImpl::kBufferSize = 4096;
32
33 // static
34 const InputStreamImpl* InputStreamImpl::FromInputStream(
35 const InputStream* input_stream) {
36 return static_cast<const InputStreamImpl*>(input_stream);
37 }
38
39 // TODO: Use unsafe version for all Java_InputStream methods in this file
40 // once BUG 157880 is fixed and implement graceful exception handling.
41
42 InputStreamImpl::InputStreamImpl() {
43 }
44
45 InputStreamImpl::InputStreamImpl(const JavaRef<jobject>& stream)
46 : jobject_(stream) {
47 DCHECK(!stream.is_null());
48 }
49
50 InputStreamImpl::~InputStreamImpl() {
51 JNIEnv* env = AttachCurrentThread();
52 Java_InputStreamUtil_close(env, jobject_);
53 }
54
55 bool InputStreamImpl::BytesAvailable(int* bytes_available) const {
56 JNIEnv* env = AttachCurrentThread();
57 int bytes = Java_InputStreamUtil_available(env, jobject_);
58 if (bytes == kExceptionThrownStatusCode)
59 return false;
60 *bytes_available = bytes;
61 return true;
62 }
63
64 bool InputStreamImpl::Skip(int64_t n, int64_t* bytes_skipped) {
65 JNIEnv* env = AttachCurrentThread();
66 int bytes = Java_InputStreamUtil_skip(env, jobject_, n);
67 if (bytes < 0)
68 return false;
69 if (bytes > n)
70 return false;
71 *bytes_skipped = bytes;
72 return true;
73 }
74
75 bool InputStreamImpl::Read(net::IOBuffer* dest, int length, int* bytes_read) {
76 JNIEnv* env = AttachCurrentThread();
77 if (!buffer_.obj()) {
78 // Allocate transfer buffer.
79 base::android::ScopedJavaLocalRef<jbyteArray> temp(
80 env, env->NewByteArray(kBufferSize));
81 buffer_.Reset(temp);
82 if (ClearException(env))
83 return false;
84 }
85
86 int remaining_length = length;
87 char* dest_write_ptr = dest->data();
88 *bytes_read = 0;
89
90 while (remaining_length > 0) {
91 const int max_transfer_length = std::min(remaining_length, kBufferSize);
92 const int transfer_length = Java_InputStreamUtil_read(
93 env, jobject_, buffer_, 0, max_transfer_length);
94 if (transfer_length == kExceptionThrownStatusCode)
95 return false;
96
97 if (transfer_length < 0) // EOF
98 break;
99
100 // Note: it is possible, yet unlikely, that the Java InputStream returns
101 // a transfer_length == 0 from time to time. In such cases we just continue
102 // the read until we get either valid data or reach EOF.
103 if (transfer_length == 0)
104 continue;
105
106 DCHECK_GE(max_transfer_length, transfer_length);
107 DCHECK_GE(env->GetArrayLength(buffer_.obj()), transfer_length);
108
109 // This check is to prevent a malicious InputStream implementation from
110 // overrunning the |dest| buffer.
111 if (transfer_length > max_transfer_length)
112 return false;
113
114 // Copy the data over to the provided C++ IOBuffer.
115 DCHECK_GE(remaining_length, transfer_length);
116 env->GetByteArrayRegion(buffer_.obj(), 0, transfer_length,
117 reinterpret_cast<jbyte*>(dest_write_ptr));
118 if (ClearException(env))
119 return false;
120
121 remaining_length -= transfer_length;
122 dest_write_ptr += transfer_length;
123 }
124 // bytes_read can be strictly less than the req. length if EOF is encountered.
125 DCHECK_GE(remaining_length, 0);
126 DCHECK_LE(remaining_length, length);
127 *bytes_read = length - remaining_length;
128 return true;
129 }
130
131 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698