@@ -143,7 +143,10 @@ private RTCDataChannel() {
143143 public native void dispose ();
144144
145145 /**
146- * Sends data in the provided buffer to the remote peer.
146+ * Sends data in the provided buffer to the remote peer. Only the bytes
147+ * between the buffer's position and limit are sent, for heap and direct
148+ * buffers alike. The buffer is read through a duplicate, so the caller's
149+ * position is left untouched.
147150 *
148151 * @param buffer The buffer to be queued for transmission.
149152 *
@@ -154,21 +157,37 @@ public void send(RTCDataChannelBuffer buffer) throws Exception {
154157 ByteBuffer data = buffer .data ;
155158
156159 if (data .isDirect ()) {
157- sendDirectBuffer (data , buffer .binary );
158- }
159- else {
160- byte [] arrayBuffer ;
161-
162- if (data .hasArray ()) {
163- arrayBuffer = data .array ();
160+ if (data .position () == 0 && data .limit () == data .capacity ()) {
161+ sendDirectBuffer (data , buffer .binary );
164162 }
165163 else {
166- arrayBuffer = new byte [data .remaining ()];
167- data .get (arrayBuffer );
164+ ByteBuffer window = ByteBuffer .allocateDirect (data .remaining ());
165+ window .put (data .duplicate ());
166+ window .flip ();
167+ sendDirectBuffer (window , buffer .binary );
168168 }
169+ }
170+ else {
171+ sendByteArrayBuffer (copyWindow (data ), buffer .binary );
172+ }
173+ }
169174
170- sendByteArrayBuffer (arrayBuffer , buffer .binary );
175+ /**
176+ * Copies the readable window of a heap buffer, position to limit, into a
177+ * fresh array for the byte array send path, which transmits whole arrays.
178+ * The backing array is handed over directly only when the window covers
179+ * it exactly; bytes outside the window (a nonzero position, a short
180+ * limit, an array offset) must never reach the wire. Reads through a
181+ * duplicate, so the caller's position is left untouched.
182+ */
183+ private static byte [] copyWindow (ByteBuffer data ) {
184+ if (data .hasArray () && data .arrayOffset () == 0 && data .position () == 0
185+ && data .remaining () == data .array ().length ) {
186+ return data .array ();
171187 }
188+ byte [] window = new byte [data .remaining ()];
189+ data .duplicate ().get (window );
190+ return window ;
172191 }
173192
174193 private native void sendDirectBuffer (ByteBuffer buffer , boolean binary );
0 commit comments