Chromium Code Reviews| 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.base.VisibleForTesting; | 7 import org.chromium.base.VisibleForTesting; |
| 8 import org.chromium.net.UploadDataProvider; | 8 import org.chromium.net.UploadDataProvider; |
| 9 import org.chromium.net.UploadDataSink; | 9 import org.chromium.net.UploadDataSink; |
| 10 | 10 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 53 int bufferSize = (int) Math.min(mContentLength, sDefaultBufferLength); | 53 int bufferSize = (int) Math.min(mContentLength, sDefaultBufferLength); |
| 54 mBuffer = ByteBuffer.allocate(bufferSize); | 54 mBuffer = ByteBuffer.allocate(bufferSize); |
| 55 mConnection = connection; | 55 mConnection = connection; |
| 56 mMessageLoop = messageLoop; | 56 mMessageLoop = messageLoop; |
| 57 mBytesWritten = 0; | 57 mBytesWritten = 0; |
| 58 } | 58 } |
| 59 | 59 |
| 60 @Override | 60 @Override |
| 61 public void write(int oneByte) throws IOException { | 61 public void write(int oneByte) throws IOException { |
| 62 checkNotExceedContentLength(1); | 62 checkNotExceedContentLength(1); |
| 63 while (mBuffer.position() == mBuffer.limit()) { | 63 maybeWaitUntilBufferConsumed(); |
| 64 // Wait until buffer is consumed. | |
| 65 mMessageLoop.loop(); | |
| 66 } | |
| 67 mBuffer.put((byte) oneByte); | 64 mBuffer.put((byte) oneByte); |
| 68 mBytesWritten++; | 65 mBytesWritten++; |
| 69 if (mBytesWritten == mContentLength) { | 66 if (mBytesWritten == mContentLength) { |
| 67 mBuffer.flip(); | |
| 70 // Entire post data has been received. Now wait for network stack to | 68 // Entire post data has been received. Now wait for network stack to |
| 71 // read it. | 69 // read it. |
| 72 mMessageLoop.loop(); | 70 mMessageLoop.loop(); |
| 73 } | 71 } |
| 74 } | 72 } |
| 75 | 73 |
| 76 @Override | 74 @Override |
| 77 public void write(byte[] buffer, int offset, int count) throws IOException { | 75 public void write(byte[] buffer, int offset, int count) throws IOException { |
| 78 if (buffer.length - offset < count || offset < 0 || count < 0) { | 76 if (buffer.length - offset < count || offset < 0 || count < 0) { |
| 79 throw new IndexOutOfBoundsException(); | 77 throw new IndexOutOfBoundsException(); |
| 80 } | 78 } |
| 81 checkNotExceedContentLength(count); | 79 checkNotExceedContentLength(count); |
| 82 if (count == 0) { | 80 if (count == 0) { |
| 83 return; | 81 return; |
| 84 } | 82 } |
|
pauljensen
2016/06/10 15:05:25
is there an important benfit to this early return
xunjieli
2016/06/10 16:09:18
Done.
| |
| 85 int toSend = count; | 83 int toSend = count; |
| 86 while (toSend > 0) { | 84 while (toSend > 0) { |
| 87 if (mBuffer.position() == mBuffer.limit()) { | 85 maybeWaitUntilBufferConsumed(); |
| 88 // Wait until buffer is consumed. | 86 int sent = Math.min(toSend, mBuffer.remaining()); |
| 89 mMessageLoop.loop(); | |
| 90 } | |
| 91 int sent = Math.min(toSend, mBuffer.limit() - mBuffer.position()); | |
| 92 mBuffer.put(buffer, offset + count - toSend, sent); | 87 mBuffer.put(buffer, offset + count - toSend, sent); |
| 93 toSend -= sent; | 88 toSend -= sent; |
| 94 } | 89 } |
| 95 mBytesWritten += count; | 90 mBytesWritten += count; |
| 96 if (mBytesWritten == mContentLength) { | 91 if (mBytesWritten == mContentLength) { |
| 92 mBuffer.flip(); | |
| 97 // Entire post data has been received. Now wait for network stack to | 93 // Entire post data has been received. Now wait for network stack to |
| 98 // read it. | 94 // read it. |
| 99 mMessageLoop.loop(); | 95 mMessageLoop.loop(); |
|
pauljensen
2016/06/10 15:05:25
can we combine these two lines from here and line
xunjieli
2016/06/10 16:09:18
Done.
| |
| 100 } | 96 } |
|
pauljensen
2016/06/10 15:05:25
can we combine this if-statement with the one on l
xunjieli
2016/06/10 16:09:18
Done.
| |
| 101 } | 97 } |
| 102 | 98 |
| 103 /** | 99 /** |
| 100 * If mBuffer is full, wait until {@code mBuffer} is consumed and there is | |
| 101 * space to write more data to it. | |
| 102 */ | |
| 103 private void maybeWaitUntilBufferConsumed() { | |
|
pauljensen
2016/06/10 15:05:25
can we rename this to something a little easier to
xunjieli
2016/06/10 16:09:18
Done.
| |
| 104 while (mBuffer.position() == mBuffer.limit()) { | |
| 105 mBuffer.flip(); | |
|
pauljensen
2016/06/10 15:05:25
I don't think flip() should be in the loop as it h
xunjieli
2016/06/10 16:09:18
Done.
| |
| 106 // Wait until buffer is consumed. | |
| 107 mMessageLoop.loop(); | |
| 108 } | |
| 109 } | |
| 110 | |
| 111 /** | |
| 104 * Throws {@link java.net.ProtocolException} if adding {@code numBytes} will | 112 * Throws {@link java.net.ProtocolException} if adding {@code numBytes} will |
| 105 * exceed content length. | 113 * exceed content length. |
| 106 */ | 114 */ |
| 107 private void checkNotExceedContentLength(int numBytes) throws ProtocolExcept ion { | 115 private void checkNotExceedContentLength(int numBytes) throws ProtocolExcept ion { |
| 108 if (mBytesWritten + numBytes > mContentLength) { | 116 if (mBytesWritten + numBytes > mContentLength) { |
| 109 throw new ProtocolException("expected " | 117 throw new ProtocolException("expected " |
| 110 + (mContentLength - mBytesWritten) + " bytes but received " | 118 + (mContentLength - mBytesWritten) + " bytes but received " |
| 111 + numBytes); | 119 + numBytes); |
| 112 } | 120 } |
| 113 } | 121 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 134 } | 142 } |
| 135 | 143 |
| 136 private class UploadDataProviderImpl extends UploadDataProvider { | 144 private class UploadDataProviderImpl extends UploadDataProvider { |
| 137 @Override | 145 @Override |
| 138 public long getLength() { | 146 public long getLength() { |
| 139 return mContentLength; | 147 return mContentLength; |
| 140 } | 148 } |
| 141 | 149 |
| 142 @Override | 150 @Override |
| 143 public void read(final UploadDataSink uploadDataSink, final ByteBuffer b yteBuffer) { | 151 public void read(final UploadDataSink uploadDataSink, final ByteBuffer b yteBuffer) { |
| 144 final int availableSpace = byteBuffer.remaining(); | 152 if (byteBuffer.remaining() >= mBuffer.remaining()) { |
| 145 if (availableSpace < mBuffer.position()) { | |
| 146 // byteBuffer does not have enough capacity, so only put a porti on | |
| 147 // of mBuffer in it. | |
| 148 byteBuffer.put(mBuffer.array(), 0, availableSpace); | |
| 149 mBuffer.position(availableSpace); | |
| 150 // Move remaining buffer to the head of the buffer for use in th e | |
| 151 // next read call. | |
| 152 mBuffer.compact(); | |
| 153 } else { | |
| 154 // byteBuffer has enough capacity to hold the content of mBuffer . | |
| 155 mBuffer.flip(); | |
| 156 byteBuffer.put(mBuffer); | 153 byteBuffer.put(mBuffer); |
| 157 // Reuse this buffer. | 154 // Reuse this buffer. |
| 158 mBuffer.clear(); | 155 mBuffer.clear(); |
| 156 uploadDataSink.onReadSucceeded(false); | |
|
pauljensen
2016/06/10 15:05:25
any particular reason you moved this up?
xunjieli
2016/06/10 16:09:18
I think it might be better to notify the native st
| |
| 159 // Quit message loop so embedder can write more data. | 157 // Quit message loop so embedder can write more data. |
| 160 mMessageLoop.quit(); | 158 mMessageLoop.quit(); |
| 159 } else { | |
| 160 int oldLimit = mBuffer.limit(); | |
| 161 mBuffer.limit(mBuffer.position() + byteBuffer.remaining()); | |
| 162 byteBuffer.put(mBuffer); | |
| 163 mBuffer.limit(oldLimit); | |
|
pauljensen
2016/06/10 15:05:25
I was going to recommend changing this to the shor
xunjieli
2016/06/10 16:09:18
Done.
pauljensen
2016/06/10 17:45:44
Um I wasn't intending you to implement this. It's
xunjieli
2016/06/10 18:48:11
Ah, I see. I was confused by "it". Done. I have re
| |
| 164 uploadDataSink.onReadSucceeded(false); | |
| 161 } | 165 } |
| 162 uploadDataSink.onReadSucceeded(false); | |
| 163 } | 166 } |
| 164 | 167 |
| 165 @Override | 168 @Override |
| 166 public void rewind(UploadDataSink uploadDataSink) { | 169 public void rewind(UploadDataSink uploadDataSink) { |
| 167 uploadDataSink.onRewindError( | 170 uploadDataSink.onRewindError( |
| 168 new HttpRetryException("Cannot retry streamed Http body", -1 )); | 171 new HttpRetryException("Cannot retry streamed Http body", -1 )); |
| 169 } | 172 } |
| 170 } | 173 } |
| 171 | 174 |
| 172 /** | 175 /** |
| 173 * Sets the default buffer length for use in tests. | 176 * Sets the default buffer length for use in tests. |
| 174 */ | 177 */ |
| 175 @VisibleForTesting | 178 @VisibleForTesting |
| 176 static void setDefaultBufferLengthForTesting(int length) { | 179 static void setDefaultBufferLengthForTesting(int length) { |
| 177 sDefaultBufferLength = length; | 180 sDefaultBufferLength = length; |
| 178 } | 181 } |
| 179 } | 182 } |
| OLD | NEW |