| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.net.urlconnection; | 5 package org.chromium.net.urlconnection; |
| 6 | 6 |
| 7 import org.chromium.net.UploadDataProvider; | 7 import org.chromium.net.UploadDataProvider; |
| 8 import org.chromium.net.UploadDataSink; | 8 import org.chromium.net.UploadDataSink; |
| 9 | 9 |
| 10 import java.io.IOException; | 10 import java.io.IOException; |
| 11 import java.net.HttpRetryException; | 11 import java.net.HttpRetryException; |
| 12 import java.nio.ByteBuffer; | 12 import java.nio.ByteBuffer; |
| 13 | 13 |
| 14 /** | 14 /** |
| 15 * An implementation of {@link java.io.OutputStream} to send data to a server, | 15 * An implementation of {@link java.io.OutputStream} to send data to a server, |
| 16 * when {@link CronetHttpURLConnection#setChunkedStreamingMode} is used. | 16 * when {@link CronetHttpURLConnection#setChunkedStreamingMode} is used. |
| 17 * This implementation does not buffer the entire request body in memory. | 17 * This implementation does not buffer the entire request body in memory. |
| 18 * It does not support rewind. Note that {@link #write} should only be called | 18 * It does not support rewind. Note that {@link #write} should only be called |
| 19 * from the thread on which the {@link #mConnection} is created. | 19 * from the thread on which the {@link #mConnection} is created. |
| 20 */ | 20 */ |
| 21 final class CronetChunkedOutputStream extends CronetOutputStream { | 21 final class CronetChunkedOutputStream extends CronetOutputStream { |
| 22 private final CronetHttpURLConnection mConnection; | 22 private final CronetHttpURLConnection mConnection; |
| 23 private final MessageLoop mMessageLoop; | 23 private final MessageLoop mMessageLoop; |
| 24 private final ByteBuffer mBuffer; | 24 private final ByteBuffer mBuffer; |
| 25 private final UploadDataProvider mUploadDataProvider = new UploadDataProvide
rImpl(); | 25 private final UploadDataProvider mUploadDataProvider = new UploadDataProvide
rImpl(); |
| 26 private long mBytesWritten; | 26 private long mBytesWritten; |
| 27 private boolean mLastChunk = false; | 27 private boolean mLastChunk = false; |
| 28 private boolean mClosed = false; | |
| 29 | 28 |
| 30 /** | 29 /** |
| 31 * Package protected constructor. | 30 * Package protected constructor. |
| 32 * @param connection The CronetHttpURLConnection object. | 31 * @param connection The CronetHttpURLConnection object. |
| 33 * @param contentLength The content length of the request body. Non-zero for | 32 * @param contentLength The content length of the request body. Non-zero for |
| 34 * non-chunked upload. | 33 * non-chunked upload. |
| 35 */ | 34 */ |
| 36 CronetChunkedOutputStream( | 35 CronetChunkedOutputStream( |
| 37 CronetHttpURLConnection connection, int chunkLength, MessageLoop mes
sageLoop) { | 36 CronetHttpURLConnection connection, int chunkLength, MessageLoop mes
sageLoop) { |
| 38 if (connection == null) { | 37 if (connection == null) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 61 @Override | 60 @Override |
| 62 public void write(byte[] buffer, int offset, int count) throws IOException { | 61 public void write(byte[] buffer, int offset, int count) throws IOException { |
| 63 checkNotClosed(); | 62 checkNotClosed(); |
| 64 if (buffer.length - offset < count || offset < 0 || count < 0) { | 63 if (buffer.length - offset < count || offset < 0 || count < 0) { |
| 65 throw new IndexOutOfBoundsException(); | 64 throw new IndexOutOfBoundsException(); |
| 66 } | 65 } |
| 67 if (count == 0) { | 66 if (count == 0) { |
| 68 return; | 67 return; |
| 69 } | 68 } |
| 70 int toSend = count; | 69 int toSend = count; |
| 70 // TODO(xunjieli): refactor commond code with CronetFixedModeOutputStrea
m. |
| 71 while (toSend > 0) { | 71 while (toSend > 0) { |
| 72 if (mBuffer.position() == mBuffer.limit()) { | 72 if (mBuffer.position() == mBuffer.limit()) { |
| 73 checkNotClosed(); |
| 73 // Wait until buffer is consumed. | 74 // Wait until buffer is consumed. |
| 74 mMessageLoop.loop(); | 75 mMessageLoop.loop(); |
| 75 } | 76 } |
| 76 int sent = Math.min(toSend, mBuffer.limit() - mBuffer.position()); | 77 int sent = Math.min(toSend, mBuffer.limit() - mBuffer.position()); |
| 77 mBuffer.put(buffer, offset + count - toSend, sent); | 78 mBuffer.put(buffer, offset + count - toSend, sent); |
| 78 toSend -= sent; | 79 toSend -= sent; |
| 79 } | 80 } |
| 80 mBytesWritten += count; | 81 mBytesWritten += count; |
| 81 } | 82 } |
| 82 | 83 |
| 83 @Override | 84 @Override |
| 84 public void close() throws IOException { | 85 public void close() throws IOException { |
| 86 super.close(); |
| 85 // Last chunk is written. | 87 // Last chunk is written. |
| 86 mLastChunk = true; | 88 mLastChunk = true; |
| 87 mClosed = true; | |
| 88 } | |
| 89 | |
| 90 private void checkNotClosed() throws IOException { | |
| 91 if (mClosed) { | |
| 92 throw new IOException("Stream has been closed."); | |
| 93 } | |
| 94 } | 89 } |
| 95 | 90 |
| 96 // Below are CronetOutputStream implementations: | 91 // Below are CronetOutputStream implementations: |
| 97 | 92 |
| 98 @Override | 93 @Override |
| 99 void setConnected() throws IOException { | 94 void setConnected() throws IOException { |
| 100 // Do nothing. | 95 // Do nothing. |
| 101 } | 96 } |
| 102 | 97 |
| 103 @Override | 98 @Override |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 } | 137 } |
| 143 } | 138 } |
| 144 | 139 |
| 145 @Override | 140 @Override |
| 146 public void rewind(UploadDataSink uploadDataSink) { | 141 public void rewind(UploadDataSink uploadDataSink) { |
| 147 uploadDataSink.onRewindError( | 142 uploadDataSink.onRewindError( |
| 148 new HttpRetryException("Cannot retry streamed Http body", -1
)); | 143 new HttpRetryException("Cannot retry streamed Http body", -1
)); |
| 149 } | 144 } |
| 150 } | 145 } |
| 151 } | 146 } |
| OLD | NEW |