|
@@ -0,0 +1,85 @@
|
|
|
|
+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());
|
|
|
|
+ }
|
|
|
|
+}
|