jimu-decompiled/sources/okhttp3/internal/ws/WebSocketWriter.java
2025-05-13 19:24:51 +02:00

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);
}
}