< Summary

Information
Class: IceRpc.Slice.Operations.Internal.IncomingFrameExtensions
Assembly: IceRpc.Slice
File(s): /home/runner/work/icerpc-csharp/icerpc-csharp/src/IceRpc.Slice/Operations/Internal/IncomingFrameExtensions.cs
Tag: 1321_24790053727
Line coverage
80%
Covered lines: 33
Uncovered lines: 8
Coverable lines: 41
Total lines: 97
Line coverage: 80.4%
Branch coverage
60%
Covered branches: 6
Total branches: 10
Branch coverage: 60%
Method coverage
83%
Covered methods: 5
Fully covered methods: 1
Total methods: 6
Method coverage: 83.3%
Full method coverage: 16.6%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
DecodeValueAsync(...)50%22100%
DecodeSegment()50%2281.81%
PerformDecodeAsync()100%11100%
DecodeVoidAsync(...)50%2285.71%
DecodeSegment()75%4483.33%
PerformDecodeAsync()100%210%

File(s)

/home/runner/work/icerpc-csharp/icerpc-csharp/src/IceRpc.Slice/Operations/Internal/IncomingFrameExtensions.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using IceRpc.Features;
 4using IceRpc.Internal;
 5using System.IO.Pipelines;
 6using ZeroC.Slice.Codec;
 7
 8namespace IceRpc.Slice.Operations.Internal;
 9
 10/// <summary>Provides extension methods for <see cref="IncomingFrame" /> to decode its payload when this payload is
 11/// encoded with the Slice encoding.</summary>
 12internal static class IncomingFrameExtensions
 13{
 14    /// <summary>Decodes arguments or a response value from a pipe reader.</summary>
 15    /// <param name="frame">The incoming frame.</param>
 16    /// <param name="feature">The Slice feature.</param>
 17    /// <param name="baseProxy">The base proxy.</param>
 18    /// <param name="decodeFunc">The decode function for the payload arguments or return value.</param>
 19    /// <param name="cancellationToken">A cancellation token that receives the cancellation requests.</param>
 20    /// <returns>The decode value.</returns>
 21    internal static ValueTask<T> DecodeValueAsync<T>(
 22        this IncomingFrame frame,
 23        ISliceFeature feature,
 24        ISliceProxy? baseProxy,
 25        DecodeFunc<T> decodeFunc,
 26        CancellationToken cancellationToken)
 13127    {
 13128        return frame.Payload.TryReadSliceSegment(feature.MaxSegmentSize, out ReadResult readResult) ?
 13129            new(DecodeSegment(readResult)) :
 13130            PerformDecodeAsync();
 31
 32        // All the logic is in this local function.
 33        T DecodeSegment(ReadResult readResult)
 13134        {
 35            // We never call CancelPendingRead; an interceptor or middleware can but it's not correct.
 13136            if (readResult.IsCanceled)
 037            {
 038                throw new InvalidOperationException("Unexpected call to CancelPendingRead.");
 39            }
 40
 13141            var decoder = new SliceDecoder(readResult.Buffer, baseProxy, feature.MaxCollectionAllocation);
 13142            T value = decodeFunc(ref decoder);
 13143            decoder.SkipTagged();
 13144            decoder.CheckEndOfBuffer();
 45
 13146            frame.Payload.AdvanceTo(readResult.Buffer.End);
 13147            return value;
 13148        }
 49
 50        async ValueTask<T> PerformDecodeAsync() =>
 451            DecodeSegment(await frame.Payload.ReadSliceSegmentAsync(
 452                feature.MaxSegmentSize,
 453                cancellationToken).ConfigureAwait(false));
 13154    }
 55
 56    /// <summary>Reads/decodes empty args or a void return value.</summary>
 57    /// <param name="frame">The incoming frame.</param>
 58    /// <param name="feature">The Slice feature.</param>
 59    /// <param name="cancellationToken">A cancellation token that receives the cancellation requests.</param>
 60    internal static ValueTask DecodeVoidAsync(
 61        this IncomingFrame frame,
 62        ISliceFeature feature,
 63        CancellationToken cancellationToken)
 3764    {
 3765        if (frame.Payload.TryReadSliceSegment(feature.MaxSegmentSize, out ReadResult readResult))
 3766        {
 3767            DecodeSegment(readResult);
 3768            return default;
 69        }
 70
 071        return PerformDecodeAsync();
 72
 73        // All the logic is in this local function.
 74        void DecodeSegment(ReadResult readResult)
 3775        {
 76            // We never call CancelPendingRead; an interceptor or middleware can but it's not correct.
 3777            if (readResult.IsCanceled)
 078            {
 079                throw new InvalidOperationException("Unexpected call to CancelPendingRead.");
 80            }
 81
 3782            if (!readResult.Buffer.IsEmpty)
 1283            {
 84                // No need to pass maxCollectionAllocation since the only thing this decoding does is skip unknown tags.
 1285                var decoder = new SliceDecoder(readResult.Buffer);
 1286                decoder.SkipTagged();
 1287                decoder.CheckEndOfBuffer();
 1288            }
 3789            frame.Payload.AdvanceTo(readResult.Buffer.End);
 3790        }
 91
 92        async ValueTask PerformDecodeAsync() =>
 093            DecodeSegment(await frame.Payload.ReadSliceSegmentAsync(
 094                feature.MaxSegmentSize,
 095                cancellationToken).ConfigureAwait(false));
 3796    }
 97}