Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 30 additions & 11 deletions webrtc/src/main/java/dev/onvoid/webrtc/RTCDataChannel.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,10 @@ private RTCDataChannel() {
public native void dispose();

/**
* Sends data in the provided buffer to the remote peer.
* Sends data in the provided buffer to the remote peer. Only the bytes
* between the buffer's position and limit are sent, for heap and direct
* buffers alike. The buffer is read through a duplicate, so the caller's
* position is left untouched.
*
* @param buffer The buffer to be queued for transmission.
*
Expand All @@ -154,21 +157,37 @@ public void send(RTCDataChannelBuffer buffer) throws Exception {
ByteBuffer data = buffer.data;

if (data.isDirect()) {
sendDirectBuffer(data, buffer.binary);
}
else {
byte[] arrayBuffer;

if (data.hasArray()) {
arrayBuffer = data.array();
if (data.position() == 0 && data.limit() == data.capacity()) {
sendDirectBuffer(data, buffer.binary);
}
else {
arrayBuffer = new byte[data.remaining()];
data.get(arrayBuffer);
ByteBuffer window = ByteBuffer.allocateDirect(data.remaining());
window.put(data.duplicate());
window.flip();
sendDirectBuffer(window, buffer.binary);
}
}
else {
sendByteArrayBuffer(copyWindow(data), buffer.binary);
}
}

sendByteArrayBuffer(arrayBuffer, buffer.binary);
/**
* Copies the readable window of a heap buffer, position to limit, into a
* fresh array for the byte array send path, which transmits whole arrays.
* The backing array is handed over directly only when the window covers
* it exactly; bytes outside the window (a nonzero position, a short
* limit, an array offset) must never reach the wire. Reads through a
* duplicate, so the caller's position is left untouched.
*/
private static byte[] copyWindow(ByteBuffer data) {
if (data.hasArray() && data.arrayOffset() == 0 && data.position() == 0
&& data.remaining() == data.array().length) {
return data.array();
}
byte[] window = new byte[data.remaining()];
data.duplicate().get(window);
return window;
}

private native void sendDirectBuffer(ByteBuffer buffer, boolean binary);
Expand Down