Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 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 package org.chromium.net.urlconnection; | |
| 6 | |
| 7 import org.chromium.net.UploadDataProvider; | |
| 8 import org.chromium.net.UploadDataSink; | |
| 9 | |
| 10 import java.io.IOException; | |
| 11 import java.io.OutputStream; | |
| 12 import java.nio.ByteBuffer; | |
| 13 | |
| 14 /** | |
| 15 * An implementation of {@link java.io.OutputStream} to send data to a server, | |
| 16 * when {@link CronetHttpURLConnection#setFixedLengthStreamingMode} is used. | |
| 17 * This implementation does not buffer entire request body in memory. | |
|
pauljensen
2015/03/10 17:31:06
What threads do we expect this to be called from?
xunjieli
2015/03/12 21:55:10
I guess I was assuming that writes happen on the t
| |
| 18 */ | |
| 19 final class CronetOutputStream extends OutputStream implements UploadDataProvide r { | |
| 20 // CronetOutputStream buffers up to this value and wait for UploadDataStream | |
| 21 // to consume the data. | |
| 22 // FIXME: confirm this number is what we want to buffer internally. | |
|
pauljensen
2015/03/10 17:31:06
can we either resolve this FIXME now or change it
xunjieli
2015/03/12 21:55:10
Done.
| |
| 23 private static int sDefaultBufferLength = 2048; | |
| 24 private final CronetHttpURLConnection mConnection; | |
| 25 private final long mContentLength; | |
| 26 private final ByteBuffer mBuffer; | |
| 27 private long mBytesReceived; | |
| 28 | |
| 29 /** | |
| 30 * Packaged protected constructor. | |
| 31 * @param connection The CronetHttpURLConnection object. | |
| 32 * @param contentLength The content length of the request body. Non-zero for | |
| 33 * non-chunked upload. | |
| 34 */ | |
| 35 CronetOutputStream(CronetHttpURLConnection connection, long contentLength) { | |
| 36 if (connection == null) { | |
| 37 throw new NullPointerException(); | |
| 38 } | |
| 39 if (contentLength < 0) { | |
| 40 throw new IllegalArgumentException( | |
| 41 "Content length must be larger than 0 for non-chunked upload ."); | |
| 42 } | |
| 43 mContentLength = contentLength; | |
| 44 int bufferSize = (int) Math.min(mContentLength, sDefaultBufferLength); | |
| 45 mBuffer = ByteBuffer.allocate(bufferSize); | |
| 46 mConnection = connection; | |
| 47 mBytesReceived = 0; | |
| 48 } | |
| 49 | |
| 50 @Override | |
| 51 public long getLength() { | |
| 52 return mContentLength; | |
| 53 } | |
| 54 | |
| 55 @Override | |
| 56 public void read(UploadDataSink uploadDataSink, ByteBuffer byteBuffer) { | |
| 57 mBuffer.flip(); | |
| 58 byteBuffer.put(mBuffer); | |
|
pauljensen
2015/03/10 17:31:06
how do we know this won't overflow? can we add a
xunjieli
2015/03/12 21:55:10
Sorry, I think there's a risk of overflowing.
Don
| |
| 59 // Reuse this buffer. | |
| 60 mBuffer.clear(); | |
| 61 uploadDataSink.onReadSucceeded(false); | |
| 62 // Wait for more data if not enough data is received. | |
| 63 if (mBytesReceived < mContentLength) { | |
| 64 mConnection.waitForPostData(); | |
| 65 } | |
| 66 } | |
| 67 | |
| 68 @Override | |
| 69 public void rewind(UploadDataSink uploadDataSink) { | |
| 70 uploadDataSink.onRewindError(null); | |
| 71 } | |
| 72 | |
| 73 @Override | |
| 74 public void write(int oneByte) throws IOException { | |
| 75 if (mBuffer.position() == mBuffer.limit()) { | |
| 76 // Wait until buffer is consumed. | |
| 77 mConnection.waitForPostDataConsumed(); | |
| 78 } | |
| 79 mBuffer.put((byte) oneByte); | |
| 80 mBytesReceived++; | |
| 81 if (mBytesReceived == mContentLength) { | |
| 82 // Entire post data has been received. Now wait for network stack to | |
| 83 // consume it. | |
| 84 mConnection.waitForPostDataConsumed(); | |
| 85 } | |
| 86 } | |
| 87 | |
| 88 @Override | |
| 89 public void write(byte[] buffer, int offset, int count) throws IOException { | |
| 90 if (buffer.length - offset < count || offset < 0 || count < 0) { | |
| 91 throw new IndexOutOfBoundsException(); | |
| 92 } | |
| 93 if (count == 0) { | |
| 94 return; | |
| 95 } | |
| 96 int toSent = count; | |
|
pauljensen
2015/03/10 17:31:06
how about renaming toSent to toSend
xunjieli
2015/03/12 21:55:10
Done.
| |
| 97 while (toSent > 0) { | |
| 98 if (mBuffer.position() == mBuffer.limit()) { | |
| 99 // Wait until buffer is consumed. | |
| 100 mConnection.waitForPostDataConsumed(); | |
| 101 } | |
| 102 int sent = Math.min(toSent, mBuffer.limit() - mBuffer.position()); | |
| 103 mBuffer.put(buffer, offset + count - toSent, sent); | |
| 104 toSent -= sent; | |
| 105 } | |
| 106 mBytesReceived += count; | |
| 107 if (mBytesReceived == mContentLength) { | |
| 108 // Entire post data has been received. Now wait for network stack to | |
| 109 // consume it. | |
| 110 mConnection.waitForPostDataConsumed(); | |
| 111 } | |
| 112 } | |
| 113 } | |
| OLD | NEW |