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

Side by Side Diff: components/cronet/android/java/src/org/chromium/net/urlconnection/CronetChunkedOutputStream.java

Issue 2133273002: [Cronet] Remove buffer.compact from CronetChunkedOutputStream (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fixoutput
Patch Set: self review Created 4 years, 5 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
« no previous file with comments | « no previous file | components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetChunkedOutputStreamTest.java » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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;
(...skipping 11 matching lines...) Expand all
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 28
29 /** 29 /**
30 * Package protected constructor. 30 * Package protected constructor.
31 * @param connection The CronetHttpURLConnection object. 31 * @param connection The CronetHttpURLConnection object.
32 * @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
kapishnikov 2016/07/08 23:05:12 contentLength => chunkLength
xunjieli 2016/07/11 13:40:08 Done. Good catch!
33 * non-chunked upload. 33 * non-chunked upload.
34 */ 34 */
35 CronetChunkedOutputStream( 35 CronetChunkedOutputStream(
36 CronetHttpURLConnection connection, int chunkLength, MessageLoop mes sageLoop) { 36 CronetHttpURLConnection connection, int chunkLength, MessageLoop mes sageLoop) {
37 if (connection == null) { 37 if (connection == null) {
38 throw new NullPointerException(); 38 throw new NullPointerException();
39 } 39 }
40 if (chunkLength <= 0) { 40 if (chunkLength <= 0) {
41 throw new IllegalArgumentException("chunkLength should be greater th an 0"); 41 throw new IllegalArgumentException("chunkLength should be greater th an 0");
42 } 42 }
43 mBuffer = ByteBuffer.allocate(chunkLength); 43 mBuffer = ByteBuffer.allocate(chunkLength);
44 mConnection = connection; 44 mConnection = connection;
45 mMessageLoop = messageLoop; 45 mMessageLoop = messageLoop;
46 mBytesWritten = 0; 46 mBytesWritten = 0;
47 } 47 }
48 48
49 @Override 49 @Override
50 public void write(int oneByte) throws IOException { 50 public void write(int oneByte) throws IOException {
51 checkNotClosed(); 51 ensureBufferHasRemaining();
52 while (mBuffer.position() == mBuffer.limit()) {
53 // Wait until buffer is consumed.
54 mMessageLoop.loop();
55 }
56 mBuffer.put((byte) oneByte); 52 mBuffer.put((byte) oneByte);
57 mBytesWritten++; 53 mBytesWritten++;
58 } 54 }
59 55
60 @Override 56 @Override
61 public void write(byte[] buffer, int offset, int count) throws IOException { 57 public void write(byte[] buffer, int offset, int count) throws IOException {
62 checkNotClosed(); 58 checkNotClosed();
63 if (buffer.length - offset < count || offset < 0 || count < 0) { 59 if (buffer.length - offset < count || offset < 0 || count < 0) {
64 throw new IndexOutOfBoundsException(); 60 throw new IndexOutOfBoundsException();
65 } 61 }
66 if (count == 0) {
67 return;
68 }
69 int toSend = count; 62 int toSend = count;
70 // TODO(xunjieli): refactor commond code with CronetFixedModeOutputStrea m.
71 while (toSend > 0) { 63 while (toSend > 0) {
72 if (mBuffer.position() == mBuffer.limit()) { 64 ensureBufferHasRemaining();
73 checkNotClosed(); 65 int sent = Math.min(toSend, mBuffer.remaining());
kapishnikov 2016/07/08 23:05:12 If toSend == mBuffer.remaining(), is it going to w
xunjieli 2016/07/11 13:40:08 Done. That is a great suggestion. I agree that it
74 // Wait until buffer is consumed.
75 mMessageLoop.loop();
76 }
77 int sent = Math.min(toSend, mBuffer.limit() - mBuffer.position());
78 mBuffer.put(buffer, offset + count - toSend, sent); 66 mBuffer.put(buffer, offset + count - toSend, sent);
79 toSend -= sent; 67 toSend -= sent;
80 } 68 }
81 mBytesWritten += count; 69 mBytesWritten += count;
82 } 70 }
83 71
84 @Override 72 @Override
85 public void close() throws IOException { 73 public void close() throws IOException {
86 super.close(); 74 super.close();
87 // Last chunk is written. 75 if (!mLastChunk) {
kapishnikov 2016/07/08 23:05:12 Should we make it thread safe?
xunjieli 2016/07/11 13:40:08 HttpURLConnection is not thread-safe. The APIs are
88 mLastChunk = true; 76 // Consumer can only call close() when message loop is not running.
77 // Set mLastChunk to be true and flip mBuffer to upload its contents .
78 mLastChunk = true;
79 mBuffer.flip();
80 }
89 } 81 }
90 82
91 // Below are CronetOutputStream implementations: 83 // Below are CronetOutputStream implementations:
92 84
93 @Override 85 @Override
94 void setConnected() throws IOException { 86 void setConnected() throws IOException {
95 // Do nothing. 87 // Do nothing.
96 } 88 }
97 89
98 @Override 90 @Override
99 void checkReceivedEnoughContent() throws IOException { 91 void checkReceivedEnoughContent() throws IOException {
100 // Do nothing. 92 // Do nothing.
101 } 93 }
102 94
103 @Override 95 @Override
104 UploadDataProvider getUploadDataProvider() { 96 UploadDataProvider getUploadDataProvider() {
105 return mUploadDataProvider; 97 return mUploadDataProvider;
106 } 98 }
107 99
108 private class UploadDataProviderImpl extends UploadDataProvider { 100 private class UploadDataProviderImpl extends UploadDataProvider {
109 @Override 101 @Override
110 public long getLength() { 102 public long getLength() {
111 return -1; 103 return -1;
112 } 104 }
113 105
114 @Override 106 @Override
115 public void read(final UploadDataSink uploadDataSink, final ByteBuffer b yteBuffer) { 107 public void read(final UploadDataSink uploadDataSink, final ByteBuffer b yteBuffer) {
116 final int availableSpace = byteBuffer.remaining(); 108 if (byteBuffer.remaining() >= mBuffer.remaining()) {
xunjieli 2016/07/08 20:31:00 This is done to match the new code in CronetFixedM
117 if (availableSpace < mBuffer.position()) {
118 // byteBuffer does not have enough capacity, so only put a porti on
119 // of mBuffer in it.
120 byteBuffer.put(mBuffer.array(), 0, availableSpace);
121 mBuffer.position(availableSpace);
122 // Move remaining buffer to the head of the buffer for use in th e
123 // next read call.
124 mBuffer.compact();
125 uploadDataSink.onReadSucceeded(false);
126 } else {
127 // byteBuffer has enough capacity to hold the content of mBuffer .
128 mBuffer.flip();
129 byteBuffer.put(mBuffer); 109 byteBuffer.put(mBuffer);
130 // Reuse this buffer.
131 mBuffer.clear(); 110 mBuffer.clear();
132 uploadDataSink.onReadSucceeded(mLastChunk); 111 uploadDataSink.onReadSucceeded(mLastChunk);
133 if (!mLastChunk) { 112 if (!mLastChunk) {
134 // Quit message loop so embedder can write more data. 113 // Quit message loop so embedder can write more data.
135 mMessageLoop.quit(); 114 mMessageLoop.quit();
136 } 115 }
116 } else {
117 int oldLimit = mBuffer.limit();
118 mBuffer.limit(mBuffer.position() + byteBuffer.remaining());
119 byteBuffer.put(mBuffer);
120 mBuffer.limit(oldLimit);
121 uploadDataSink.onReadSucceeded(false);
137 } 122 }
138 } 123 }
139 124
140 @Override 125 @Override
141 public void rewind(UploadDataSink uploadDataSink) { 126 public void rewind(UploadDataSink uploadDataSink) {
142 uploadDataSink.onRewindError( 127 uploadDataSink.onRewindError(
143 new HttpRetryException("Cannot retry streamed Http body", -1 )); 128 new HttpRetryException("Cannot retry streamed Http body", -1 ));
144 } 129 }
145 } 130 }
131
132 /**
133 * If {@code mBuffer} is full, wait until it is consumed and there is
134 * space to write more data to it.
135 */
136 private void ensureBufferHasRemaining() throws IOException {
137 if (!mBuffer.hasRemaining()) {
138 uploadBufferInternal();
139 }
140 }
141
142 /**
143 * Helper function to upload {@code mBuffer} to the native stack. This
144 * function blocks until {@code mBuffer} is consumed and there is space to
145 * write more data.
146 */
147 private void uploadBufferInternal() throws IOException {
148 checkNotClosed();
149 mBuffer.flip();
150 mMessageLoop.loop();
151 }
146 } 152 }
OLDNEW
« no previous file with comments | « no previous file | components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetChunkedOutputStreamTest.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698