Smu*_*202 5 .net-core guacamole
SequenceReader<T>
我正在尝试在 .Net Core Preview 8 中使用来解析鳄梨酱协议网络流量。
流量可能如下所示:
5.error,14.some text here,1.0;
这是一个单一错误指令。有3个字段:
error
some text here
0
(参见状态代码)这些字段以逗号分隔(以分号终止),但每个字段上也有长度前缀。我想这样你就可以解析类似的东西:
5.error,24.some, text, with, commas,1.0;
产生Reason
= some, text, with, commas
.
简单的逗号分隔解析很简单(有或没有SequenceReader
)。但是,为了利用长度,我尝试了以下操作:
public static bool TryGetNextElement(this ref SerializationContext context, out ReadOnlySequence<byte> element)
{
element = default;
var start = context.Reader.Position;
if (!context.Reader.TryReadTo(out ReadOnlySequence<byte> lengthSlice, Utf8Bytes.Period, advancePastDelimiter: true))
return false;
if (!lengthSlice.TryGetInt(out var length))
return false;
context.Reader.Advance(length);
element = context.Reader.Sequence.Slice(start, context.Reader.Position);
return true;
}
Run Code Online (Sandbox Code Playgroud)
根据我对最初提案的理解,这应该可行,但我认为也可以简化,因为提案中的一些方法使生活比 .Net Core Preview 8 中提供的方法更容易一些。
然而,这段代码的问题是,它SequenceReader
似乎并不Advance
像我所期望的那样。它的Position
和Consumed
属性在前进时保持不变,因此element
最后的 I 切片始终是一个空序列。
我需要做什么才能正确解析该协议?
我猜这.Reader
是一个财产;这很重要,因为SequenceReader<T>
它是一个可变的 struct,但每次访问时,.SomeProperty
您都在使用reader 的独立副本。将其隐藏在属性后面是可以的,但是您需要确保与当地人合作,然后在完成后推回,即
var reader = context.Reader;
var start = reader.Position;
if (!reader.TryReadTo(out ReadOnlySequence<byte> lengthSlice,
Utf8Bytes.Period, advancePastDelimiter: true))
return false;
if (!lengthSlice.TryGetInt(out var length))
return false;
reader.Advance(length);
element = reader.Sequence.Slice(start, reader.Position);
context.Reader = reader; // update position
return true;
Run Code Online (Sandbox Code Playgroud)
请注意,它的一个很好的功能是,在失败情况下( return false
),您还没有更改状态,因为您只是改变了本地独立克隆。
您还可以ref
考虑的 -return 属性.Reader
。
归档时间: |
|
查看次数: |
199 次 |
最近记录: |