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

Unified Diff: components/cronet/android/api/src/org/chromium/net/InputStreamChannel.java

Issue 1492583002: Add HttpUrlConnection backed implementation of CronetEngine. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed comments Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: components/cronet/android/api/src/org/chromium/net/InputStreamChannel.java
diff --git a/components/cronet/android/api/src/org/chromium/net/InputStreamChannel.java b/components/cronet/android/api/src/org/chromium/net/InputStreamChannel.java
new file mode 100644
index 0000000000000000000000000000000000000000..cf415e7838b9677f6317d82f88671569fd4bc7e7
--- /dev/null
+++ b/components/cronet/android/api/src/org/chromium/net/InputStreamChannel.java
@@ -0,0 +1,75 @@
+// Copyright 2015 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.
+
+package org.chromium.net;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.ReadableByteChannel;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Adapts an {@link InputStream} into a {@link ReadableByteChannel}, exactly like
+ * {@link java.nio.channels.Channels#newChannel(InputStream)} does, but more efficiently, since it
+ * does not allocate a temporary buffer if it doesn't have to, and it freely takes advantage of
+ * {@link FileInputStream}'s trivial conversion to {@link java.nio.channels.FileChannel}.
+ */
+final class InputStreamChannel implements ReadableByteChannel {
+ private static final int MAX_TMP_BUFFER_SIZE = 16384;
+ private static final int MIN_TMP_BUFFER_SIZE = 4096;
+ private final InputStream mInputStream;
+ private final AtomicBoolean mIsOpen = new AtomicBoolean(true);
+
+ private InputStreamChannel(InputStream inputStream) {
+ mInputStream = inputStream;
+ }
+
+ static ReadableByteChannel wrap(InputStream inputStream) {
+ if (inputStream instanceof FileInputStream) {
+ return ((FileInputStream) inputStream).getChannel();
+ }
+ return new InputStreamChannel(inputStream);
+ }
+
+ @Override
+ public int read(ByteBuffer dst) throws IOException {
+ final int read;
+ if (dst.hasArray()) {
+ read = mInputStream.read(
+ dst.array(), dst.arrayOffset() + dst.position(), dst.remaining());
+ if (read > 0) {
+ dst.position(dst.position() + read);
+ }
+ } else {
+ // Since we're allocating a buffer for every read, we want to choose a good size - on
+ // Android, the only case where a ByteBuffer won't have a backing byte[] is if it was
+ // created wrapping a void * in native code, or if it represents a memory-mapped file.
+ // Especially in the latter case, we want to avoid allocating a buffer that could be
+ // very large.
+ final int possibleToRead = Math.min(
+ Math.max(mInputStream.available(), MIN_TMP_BUFFER_SIZE), dst.remaining());
+ final int reasonableToRead = Math.min(MAX_TMP_BUFFER_SIZE, possibleToRead);
+ byte[] tmpBuf = new byte[reasonableToRead];
+ read = mInputStream.read(tmpBuf);
+ if (read > 0) {
+ dst.put(tmpBuf, 0, read);
+ }
+ }
+ return read;
+ }
+
+ @Override
+ public boolean isOpen() {
+ return mIsOpen.get();
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (mIsOpen.compareAndSet(true, false)) {
+ mInputStream.close();
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698