|
|
|
|
using DotNetty.Buffers;
|
|
|
|
|
using DotNetty.Codecs;
|
|
|
|
|
using DotNetty.Transport.Channels;
|
|
|
|
|
using log4net;
|
|
|
|
|
using Service.Car.Common;
|
|
|
|
|
|
|
|
|
|
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<object> output)
|
|
|
|
|
{
|
|
|
|
|
IByteBuffer? delimiter = FindDelimiter(buffer);
|
|
|
|
|
if (delimiter != null)
|
|
|
|
|
{
|
|
|
|
|
//分隔符索引
|
|
|
|
|
int delimiterIndex = IndexOf(buffer, delimiter);
|
|
|
|
|
//帧长索引
|
|
|
|
|
int frameLengthIndex = delimiterIndex + delimiter.Capacity;
|
|
|
|
|
|
|
|
|
|
if (delimiterIndex > 0)
|
|
|
|
|
{
|
|
|
|
|
buffer.SkipBytes(delimiterIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (buffer.ReadableBytes < frameLengthIndex + 2)
|
|
|
|
|
{
|
|
|
|
|
// 数据不足,等待更多数据
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 读取长度字段
|
|
|
|
|
int frameLength = buffer.GetUnsignedShortLE(buffer.ReaderIndex + frameLengthIndex);
|
|
|
|
|
|
|
|
|
|
if (buffer.ReadableBytes < frameLength)
|
|
|
|
|
{
|
|
|
|
|
// 数据不足,等待更多数据
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buffer.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|