LengthFieldPayloadParserBuilder.java
package org.jetlinks.community.network.tcp.parser;
import io.vertx.core.buffer.Buffer;
import lombok.SneakyThrows;
import org.jetlinks.community.ValueObject;
import org.jetlinks.community.network.tcp.parser.strateies.PipePayloadParser;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* 长度字段粘拆包解析规则, 使用指定的字节数据来表示接下来的包长度.
*
* @author zhouhao
* @since 1.0
*/
public class LengthFieldPayloadParserBuilder implements PayloadParserBuilderStrategy {
@Override
public PayloadParserType getType() {
return PayloadParserType.LENGTH_FIELD;
}
@Override
@SneakyThrows
public Supplier<PayloadParser> buildLazy(ValueObject config) {
//偏移量
int offset = config.getInt("offset")
.orElse(0);
//包长度
int len = config.getInt("length")
.orElseGet(() -> config
.getInt("to")
.orElse(4) - offset);
//是否为小端模式
boolean le = config.getBoolean("little")
.orElse(false);
int initLength = offset + len;
Function<Buffer, Integer> lengthParser;
switch (len) {
case 1:
lengthParser = buffer -> (int) buffer.getUnsignedByte(offset);
break;
case 2:
lengthParser =
le ? buffer -> buffer.getUnsignedShort(offset)
: buffer -> buffer.getUnsignedShort(offset);
break;
case 3:
lengthParser =
le ? buffer -> buffer.getUnsignedMediumLE(offset)
: buffer -> (int) buffer.getUnsignedMedium(offset);
break;
case 4:
lengthParser =
le ? buffer -> buffer.getIntLE(offset)
: buffer -> (int) buffer.getInt(offset);
break;
case 8:
lengthParser =
le ? buffer -> (int) buffer.getLongLE(offset)
: buffer -> (int) buffer.getLong(offset);
break;
default:
throw new IllegalArgumentException("illegal length:" + len);
}
return () -> new PipePayloadParser()
//先读取初始长度
.fixed(initLength)
.handler((buffer, parser) -> {
//获取长度字段,然后读取接下来的长度
int next = lengthParser.apply(buffer);
parser.result(buffer)
.fixed(next);
})
.handler((buffer, parser) -> parser
.result(buffer)
.complete());
}
}