|
@@ -43,18 +43,37 @@ namespace Google.Protobuf
|
|
|
/// </summary>
|
|
|
internal struct SegmentedBufferHelper
|
|
|
{
|
|
|
- private readonly int? totalLength;
|
|
|
+ private int? totalLength;
|
|
|
private ReadOnlySequence<byte>.Enumerator readOnlySequenceEnumerator;
|
|
|
- private readonly CodedInputStream codedInputStream;
|
|
|
+ private CodedInputStream codedInputStream;
|
|
|
|
|
|
- public SegmentedBufferHelper(ReadOnlySequence<byte> sequence, out ReadOnlySpan<byte> firstSpan)
|
|
|
+ /// <summary>
|
|
|
+ /// Initialize an instance with a coded input stream.
|
|
|
+ /// This approach is faster than using a constructor because the instance to initialize is passed by reference
|
|
|
+ /// and we can write directly into it without copying.
|
|
|
+ /// </summary>
|
|
|
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
+ public static void Initialize(CodedInputStream codedInputStream, out SegmentedBufferHelper instance)
|
|
|
+ {
|
|
|
+ instance.totalLength = codedInputStream.InternalInputStream == null ? (int?)codedInputStream.InternalBuffer.Length : null;
|
|
|
+ instance.readOnlySequenceEnumerator = default;
|
|
|
+ instance.codedInputStream = codedInputStream;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Initialize an instance with a read only sequence.
|
|
|
+ /// This approach is faster than using a constructor because the instance to initialize is passed by reference
|
|
|
+ /// and we can write directly into it without copying.
|
|
|
+ /// </summary>
|
|
|
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
+ public static void Initialize(ReadOnlySequence<byte> sequence, out SegmentedBufferHelper instance, out ReadOnlySpan<byte> firstSpan)
|
|
|
{
|
|
|
- this.codedInputStream = null;
|
|
|
+ instance.codedInputStream = null;
|
|
|
if (sequence.IsSingleSegment)
|
|
|
{
|
|
|
firstSpan = sequence.First.Span;
|
|
|
- this.totalLength = firstSpan.Length;
|
|
|
- this.readOnlySequenceEnumerator = default;
|
|
|
+ instance.totalLength = firstSpan.Length;
|
|
|
+ instance.readOnlySequenceEnumerator = default;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -62,17 +81,10 @@ namespace Google.Protobuf
|
|
|
// very first read will result in slowpath (because the first thing to do is to
|
|
|
// refill to get the first buffer segment)
|
|
|
firstSpan = default;
|
|
|
- this.totalLength = (int) sequence.Length;
|
|
|
- this.readOnlySequenceEnumerator = sequence.GetEnumerator();
|
|
|
+ instance.totalLength = (int) sequence.Length;
|
|
|
+ instance.readOnlySequenceEnumerator = sequence.GetEnumerator();
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- public SegmentedBufferHelper(CodedInputStream codedInputStream)
|
|
|
- {
|
|
|
- this.totalLength = codedInputStream.InternalInputStream == null ? (int?)codedInputStream.InternalBuffer.Length : null;
|
|
|
- this.readOnlySequenceEnumerator = default;
|
|
|
- this.codedInputStream = codedInputStream;
|
|
|
- }
|
|
|
|
|
|
public bool RefillBuffer(ref ReadOnlySpan<byte> buffer, ref ParserInternalState state, bool mustSucceed)
|
|
|
{
|