
swim.ws.WsFrameInflater Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of swim-ws Show documentation
Show all versions of swim-ws Show documentation
Uploads all artifacts belonging to configuration ':swim-ws:archives'
// Copyright 2015-2019 SWIM.AI inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package swim.ws;
import swim.codec.Decoder;
import swim.codec.DecoderException;
import swim.codec.InputBuffer;
import swim.deflate.DeflateException;
import swim.deflate.Inflate;
final class WsFrameInflater extends Decoder> {
final WsDeflateDecoder ws;
final Decoder content;
final int finRsvOp;
final long position;
final long offset;
final long length;
final byte[] maskingKey;
final int step;
WsFrameInflater(WsDeflateDecoder ws, Decoder content, int finRsvOp, long position,
long offset, long length, byte[] maskingKey, int step) {
this.ws = ws;
this.content = content;
this.finRsvOp = finRsvOp;
this.position = position;
this.offset = offset;
this.length = length;
this.maskingKey = maskingKey;
this.step = step;
}
WsFrameInflater(WsDeflateDecoder ws, Decoder content) {
this(ws, content, 0, 0L, 0L, 0L, null, 1);
}
@Override
public Decoder> feed(InputBuffer input) {
return decode(input, this.ws, this.content, this.finRsvOp, this.position,
this.offset, this.length, this.maskingKey, this.step);
}
@SuppressWarnings("unchecked")
static Decoder> decode(InputBuffer input, WsDeflateDecoder ws, Decoder content,
int finRsvOp, long position, long offset, long length,
byte[] maskingKey, int step) {
if (step == 1 && input.isCont()) { // decode finRsvOp
finRsvOp = input.head();
input = input.step();
step = 2;
}
if (step == 2 && input.isCont()) { // decode maskLength
final int maskLength = input.head();
input = input.step();
if ((maskLength & 0x80) != 0) {
maskingKey = new byte[4];
}
final int len = maskLength & 0x7f;
if (len == 126) { // short length
step = 3;
} else if (len == 127) { // long length
step = 5;
} else {
length = (long) len;
step = maskingKey != null ? 13 : 17;
}
}
if (step >= 3 && step <= 4) { // decode short length
while (input.isCont()) {
length = (length << 8) | (long) input.head();
input = input.step();
if (step < 4) {
step += 1;
} else {
step = maskingKey != null ? 13 : 17;
break;
}
}
}
if (step >= 5 && step <= 12) { // decode long length
while (input.isCont()) {
length = (length << 8) | (long) input.head();
input = input.step();
if (step < 12) {
step += 1;
} else {
step = maskingKey != null ? 13 : 17;
break;
}
}
}
if (step >= 13 && step <= 16) { // decode masking key
while (input.isCont()) {
maskingKey[step - 13] = (byte) input.head();
input = input.step();
if (step < 16) {
step += 1;
} else {
step = 17;
break;
}
}
}
if (step == 17) { // decode payload
final int base = input.index();
final int size = (int) Math.min(length - offset, input.remaining());
if (maskingKey != null) {
for (int i = 0; i < size; i += 1) {
input.set(base + i, (input.get(base + i) ^ maskingKey[(int) (position + i) & 0x3]) & 0xff);
}
}
position += size;
offset += size;
final boolean eof = offset == length && (finRsvOp & 0x80) != 0;
ws.inflate.initWindow();
ws.inflate.next_out = ws.inflate.window;
((Inflate
© 2015 - 2025 Weber Informatics LLC | Privacy Policy