199 lines
6.9 KiB
Java
199 lines
6.9 KiB
Java
package okhttp3.internal.ws;
|
|
|
|
import android.support.v4.media.session.PlaybackStateCompat;
|
|
import com.ubtrobot.jimu.robotapi.PeripheralType;
|
|
import java.io.IOException;
|
|
import java.util.Random;
|
|
import okio.Buffer;
|
|
import okio.BufferedSink;
|
|
import okio.ByteString;
|
|
import okio.Sink;
|
|
import okio.Timeout;
|
|
|
|
/* loaded from: classes2.dex */
|
|
final class WebSocketWriter {
|
|
boolean activeWriter;
|
|
final Buffer buffer = new Buffer();
|
|
final FrameSink frameSink = new FrameSink();
|
|
final boolean isClient;
|
|
private final Buffer.UnsafeCursor maskCursor;
|
|
private final byte[] maskKey;
|
|
final Random random;
|
|
final BufferedSink sink;
|
|
final Buffer sinkBuffer;
|
|
boolean writerClosed;
|
|
|
|
final class FrameSink implements Sink {
|
|
boolean closed;
|
|
long contentLength;
|
|
int formatOpcode;
|
|
boolean isFirstFrame;
|
|
|
|
FrameSink() {
|
|
}
|
|
|
|
@Override // okio.Sink, java.io.Closeable, java.lang.AutoCloseable
|
|
public void close() throws IOException {
|
|
if (this.closed) {
|
|
throw new IOException("closed");
|
|
}
|
|
WebSocketWriter webSocketWriter = WebSocketWriter.this;
|
|
webSocketWriter.writeMessageFrame(this.formatOpcode, webSocketWriter.buffer.size(), this.isFirstFrame, true);
|
|
this.closed = true;
|
|
WebSocketWriter.this.activeWriter = false;
|
|
}
|
|
|
|
@Override // okio.Sink, java.io.Flushable
|
|
public void flush() throws IOException {
|
|
if (this.closed) {
|
|
throw new IOException("closed");
|
|
}
|
|
WebSocketWriter webSocketWriter = WebSocketWriter.this;
|
|
webSocketWriter.writeMessageFrame(this.formatOpcode, webSocketWriter.buffer.size(), this.isFirstFrame, false);
|
|
this.isFirstFrame = false;
|
|
}
|
|
|
|
@Override // okio.Sink
|
|
public Timeout timeout() {
|
|
return WebSocketWriter.this.sink.timeout();
|
|
}
|
|
|
|
@Override // okio.Sink
|
|
public void write(Buffer buffer, long j) throws IOException {
|
|
if (this.closed) {
|
|
throw new IOException("closed");
|
|
}
|
|
WebSocketWriter.this.buffer.write(buffer, j);
|
|
boolean z = this.isFirstFrame && this.contentLength != -1 && WebSocketWriter.this.buffer.size() > this.contentLength - PlaybackStateCompat.ACTION_PLAY_FROM_URI;
|
|
long completeSegmentByteCount = WebSocketWriter.this.buffer.completeSegmentByteCount();
|
|
if (completeSegmentByteCount <= 0 || z) {
|
|
return;
|
|
}
|
|
WebSocketWriter.this.writeMessageFrame(this.formatOpcode, completeSegmentByteCount, this.isFirstFrame, false);
|
|
this.isFirstFrame = false;
|
|
}
|
|
}
|
|
|
|
WebSocketWriter(boolean z, BufferedSink bufferedSink, Random random) {
|
|
if (bufferedSink == null) {
|
|
throw new NullPointerException("sink == null");
|
|
}
|
|
if (random == null) {
|
|
throw new NullPointerException("random == null");
|
|
}
|
|
this.isClient = z;
|
|
this.sink = bufferedSink;
|
|
this.sinkBuffer = bufferedSink.buffer();
|
|
this.random = random;
|
|
this.maskKey = z ? new byte[4] : null;
|
|
this.maskCursor = z ? new Buffer.UnsafeCursor() : null;
|
|
}
|
|
|
|
private void writeControlFrame(int i, ByteString byteString) throws IOException {
|
|
if (this.writerClosed) {
|
|
throw new IOException("closed");
|
|
}
|
|
int size = byteString.size();
|
|
if (size > 125) {
|
|
throw new IllegalArgumentException("Payload size must be less than or equal to 125");
|
|
}
|
|
this.sinkBuffer.writeByte(i | PeripheralType.SERVO);
|
|
if (this.isClient) {
|
|
this.sinkBuffer.writeByte(size | PeripheralType.SERVO);
|
|
this.random.nextBytes(this.maskKey);
|
|
this.sinkBuffer.write(this.maskKey);
|
|
if (size > 0) {
|
|
long size2 = this.sinkBuffer.size();
|
|
this.sinkBuffer.write(byteString);
|
|
this.sinkBuffer.readAndWriteUnsafe(this.maskCursor);
|
|
this.maskCursor.seek(size2);
|
|
WebSocketProtocol.toggleMask(this.maskCursor, this.maskKey);
|
|
this.maskCursor.close();
|
|
}
|
|
} else {
|
|
this.sinkBuffer.writeByte(size);
|
|
this.sinkBuffer.write(byteString);
|
|
}
|
|
this.sink.flush();
|
|
}
|
|
|
|
Sink newMessageSink(int i, long j) {
|
|
if (this.activeWriter) {
|
|
throw new IllegalStateException("Another message writer is active. Did you call close()?");
|
|
}
|
|
this.activeWriter = true;
|
|
FrameSink frameSink = this.frameSink;
|
|
frameSink.formatOpcode = i;
|
|
frameSink.contentLength = j;
|
|
frameSink.isFirstFrame = true;
|
|
frameSink.closed = false;
|
|
return frameSink;
|
|
}
|
|
|
|
void writeClose(int i, ByteString byteString) throws IOException {
|
|
ByteString byteString2 = ByteString.EMPTY;
|
|
if (i != 0 || byteString != null) {
|
|
if (i != 0) {
|
|
WebSocketProtocol.validateCloseCode(i);
|
|
}
|
|
Buffer buffer = new Buffer();
|
|
buffer.writeShort(i);
|
|
if (byteString != null) {
|
|
buffer.write(byteString);
|
|
}
|
|
byteString2 = buffer.readByteString();
|
|
}
|
|
try {
|
|
writeControlFrame(8, byteString2);
|
|
} finally {
|
|
this.writerClosed = true;
|
|
}
|
|
}
|
|
|
|
void writeMessageFrame(int i, long j, boolean z, boolean z2) throws IOException {
|
|
if (this.writerClosed) {
|
|
throw new IOException("closed");
|
|
}
|
|
if (!z) {
|
|
i = 0;
|
|
}
|
|
if (z2) {
|
|
i |= PeripheralType.SERVO;
|
|
}
|
|
this.sinkBuffer.writeByte(i);
|
|
int i2 = this.isClient ? PeripheralType.SERVO : 0;
|
|
if (j <= 125) {
|
|
this.sinkBuffer.writeByte(((int) j) | i2);
|
|
} else if (j <= 65535) {
|
|
this.sinkBuffer.writeByte(i2 | 126);
|
|
this.sinkBuffer.writeShort((int) j);
|
|
} else {
|
|
this.sinkBuffer.writeByte(i2 | 127);
|
|
this.sinkBuffer.writeLong(j);
|
|
}
|
|
if (this.isClient) {
|
|
this.random.nextBytes(this.maskKey);
|
|
this.sinkBuffer.write(this.maskKey);
|
|
if (j > 0) {
|
|
long size = this.sinkBuffer.size();
|
|
this.sinkBuffer.write(this.buffer, j);
|
|
this.sinkBuffer.readAndWriteUnsafe(this.maskCursor);
|
|
this.maskCursor.seek(size);
|
|
WebSocketProtocol.toggleMask(this.maskCursor, this.maskKey);
|
|
this.maskCursor.close();
|
|
}
|
|
} else {
|
|
this.sinkBuffer.write(this.buffer, j);
|
|
}
|
|
this.sink.emit();
|
|
}
|
|
|
|
void writePing(ByteString byteString) throws IOException {
|
|
writeControlFrame(9, byteString);
|
|
}
|
|
|
|
void writePong(ByteString byteString) throws IOException {
|
|
writeControlFrame(10, byteString);
|
|
}
|
|
}
|