using DotNetty.Buffers; using DotNetty.Codecs; using DotNetty.Transport.Channels; using HybirdFrameworkCore.Utils; using log4net; using Service.Car.Common; using Service.Car.Msg; using Service.Car.Msg.Car.Req; using Service.Car.Msg.Car.Resp; namespace Service.Car.Codec; public class Decoder : ByteToMessageDecoder { private static readonly ILog Log = LogManager.GetLogger(typeof(Decoder)); private readonly IByteBuffer[] _delimiters = { Unpooled.CopiedBuffer(CarConst.StartChar) }; protected override void Decode(IChannelHandlerContext context, IByteBuffer buffer, List output) { IByteBuffer? delimiter = FindDelimiter(buffer); if (delimiter != null) { //分隔符索引 int delimiterIndex = IndexOf(buffer, delimiter); //帧长索引 int frameLengthIndex = delimiterIndex + CarConst.StartChar.Length; if (delimiterIndex > 0) { buffer.SkipBytes(delimiterIndex); return; } if (buffer.ReadableBytes < frameLengthIndex) { // 数据不足,等待更多数据 return; } // 读取长度字段 int frameLength = buffer.GetUnsignedShortLE(buffer.ReaderIndex + frameLengthIndex); if (buffer.ReadableBytes < frameLength) { // 数据不足,等待更多数据 return; } var msg = Parse(buffer, frameLength); output.Add(msg); buffer.Clear(); } } private BaseMsg Parse(IByteBuffer buffer, int length) { byte[] data = new byte[length]; buffer.ReadBytes(data); return data[5] switch { 0x01 => ModelConvert.Decode(data), 0x03 => ModelConvert.Decode(data), 0x06 => ModelConvert.Decode(data), 0x08 => ModelConvert.Decode(data), 0x10 => ModelConvert.Decode(data), 0x12 => ModelConvert.Decode(data), _ => new BaseMsg() }; } private IByteBuffer? FindDelimiter(IByteBuffer buffer) { foreach (IByteBuffer delimiter in _delimiters) { int delimiterIndex = IndexOf(buffer, delimiter); if (delimiterIndex >= 0) { return delimiter; } } return null; } private static int IndexOf(IByteBuffer haystack, IByteBuffer needle) { for (int i = haystack.ReaderIndex; i < haystack.WriterIndex; i++) { int num = i; int j; for (j = 0; j < needle.Capacity && haystack.GetByte(num) == needle.GetByte(j); j++) { num++; if (num == haystack.WriterIndex && j != needle.Capacity - 1) { return -1; } } if (j == needle.Capacity) { return i - haystack.ReaderIndex; } } return -1; } }